From 3c7cf15480d57dfca0dc2acd7bda0de2a2b24a6c Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 11 Feb 2015 14:28:01 +0000 Subject: [PATCH 001/812] Update Spring Boot CLI to version 1.+ This commit updates the version of Spring Boot CLI to be used from 1.1.+ to 1.+ [#87191758] --- config/spring_boot_cli.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/spring_boot_cli.yml b/config/spring_boot_cli.yml index c5f3b52f75..c7eb15327f 100644 --- a/config/spring_boot_cli.yml +++ b/config/spring_boot_cli.yml @@ -17,5 +17,5 @@ # Note that the repository is shared with the Play Auto Reconfiguration framework and should be kept in step to # avoid conflicts. --- -version: 1.1.+ +version: 1.+ repository_root: "{default.repository.root}/spring-boot-cli" From 9858440401dae5c637d544ebcb3c2e0ade8a3132 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 12 Feb 2015 13:50:45 +0000 Subject: [PATCH 002/812] Update config file dependency versions This commit updates some of the dependency versions specified in the config files to ensure the latest versions available are being used. [#87191800] --- config/app_dynamics_agent.yml | 2 +- config/groovy.yml | 2 +- config/postgresql_jdbc.yml | 2 +- config/tomcat.yml | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 593fa9e72e..b39b66152f 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -15,6 +15,6 @@ # Configuration for the New Relic framework --- -version: 3.9.+ +version: 4.0.+ repository_root: "{default.repository.root}/app-dynamics" default_tier_name: CloudFoundry diff --git a/config/groovy.yml b/config/groovy.yml index 1d70b6cedd..d552d29e40 100644 --- a/config/groovy.yml +++ b/config/groovy.yml @@ -15,5 +15,5 @@ # Configuration for the Groovy container --- -version: 2.3.+ +version: 2.4.+ repository_root: "{default.repository.root}/groovy" diff --git a/config/postgresql_jdbc.yml b/config/postgresql_jdbc.yml index 9193fe8f0b..96d7960863 100644 --- a/config/postgresql_jdbc.yml +++ b/config/postgresql_jdbc.yml @@ -15,5 +15,5 @@ # Configuration for the Postgresql JDBC framework --- -version: 9.3.+ +version: 9.4.+ repository_root: "{default.repository.root}/postgresql-jdbc" diff --git a/config/tomcat.yml b/config/tomcat.yml index de37fe52a4..1a5e5c3c6a 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -36,16 +36,16 @@ redis_store: connection_pool_size: 2 gemfire_store: gemfire: - version: 8.0.+ + version: 8.1.+ repository_root: "{default.repository.root}/gem-fire" gemfire_modules: - version: 8.0.+ + version: 8.1.+ repository_root: "{default.repository.root}/gem-fire-modules" gemfire_modules_tomcat7: - version: 8.0.+ + version: 8.1.+ repository_root: "{default.repository.root}/gem-fire-modules-tomcat7" gemfire_security: - version: 8.0.+ + version: 8.1.+ repository_root: "{default.repository.root}/gem-fire-security" gemfire_logging: version: 1.5.8 From 50dc42c149254e2872917ae40f962093f400d88c Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Fri, 13 Feb 2015 16:34:10 +0000 Subject: [PATCH 003/812] Add support for JRebel This commit adds support for using JRebel in an IDE to live edit an application running in Cloud Foundry. No service is required, only the presense of the rebel.xml and rebel-remote.xml files in the application that get's uploaded to Cloud Foundry. These files are often generated by the IDE's JRebel plugin. [#84050588] --- README.md | 1 + config/components.yml | 1 + config/jrebel_agent.yml | 19 ++++++ docs/framework-jrebel_agent.md | 31 +++++++++ java-buildpack.iml | 4 +- lib/java_buildpack/component/java_opts.rb | 16 ++++- lib/java_buildpack/framework/jrebel_agent.rb | 62 ++++++++++++++++++ .../framework_jrebel_app/rebel-remote.xml | 0 spec/fixtures/framework_jrebel_app/rebel.xml | 0 spec/fixtures/stub-jrebel-archive.zip | Bin 0 -> 480 bytes .../framework/jrebel_agent_spec.rb | 55 ++++++++++++++++ 11 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 config/jrebel_agent.yml create mode 100644 docs/framework-jrebel_agent.md create mode 100644 lib/java_buildpack/framework/jrebel_agent.rb create mode 100644 spec/fixtures/framework_jrebel_app/rebel-remote.xml create mode 100644 spec/fixtures/framework_jrebel_app/rebel.xml create mode 100644 spec/fixtures/stub-jrebel-archive.zip create mode 100644 spec/java_buildpack/framework/jrebel_agent_spec.rb diff --git a/README.md b/README.md index 0385565fe5..71c1f52aee 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) + * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) diff --git a/config/components.yml b/config/components.yml index db5a732ae7..18b0f10732 100644 --- a/config/components.yml +++ b/config/components.yml @@ -34,6 +34,7 @@ jres: frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" - "JavaBuildpack::Framework::JavaOpts" + - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::MariaDbJDBC" - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration" diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml new file mode 100644 index 0000000000..c676f7b7cf --- /dev/null +++ b/config/jrebel_agent.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright (c) 2013 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the JRebel framework +--- +version: 6.+ +repository_root: "{default.repository.root}/jrebel" diff --git a/docs/framework-jrebel_agent.md b/docs/framework-jrebel_agent.md new file mode 100644 index 0000000000..9a44e9d090 --- /dev/null +++ b/docs/framework-jrebel_agent.md @@ -0,0 +1,31 @@ +# JRebel Agent Framework +The JRebel Agent Framework causes an application to be automatically configured to work with an IDE using [JRebel][]. + + + + + + + + + + +
Detection CriterionExistence of the `rebel.xml` and `rebel-remote.xml` files in either the root or `WEB-INF/classes` directory or the application.
Tagsjrebel-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/jrebel_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the JRebel repository index ([details][repositories]). +| `version` | The version of Jrebel to use. Candidate versions can be found in [this listing][]. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[`config/jrebel_agent.yml`]: ../config/jrebel_agent.yml +[JRebel]: http://zeroturnaround.com/software/jrebel/ +[repositories]: extending-repositories.md +[this listing]: http://download.pivotal.io.s3.amazonaws.com/jrebel/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/java-buildpack.iml b/java-buildpack.iml index a0bcb4d298..2dbb8fc634 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -281,13 +281,13 @@ - + - + diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index 6435c1c07c..d259c34b53 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -33,7 +33,7 @@ def initialize(droplet_root) @droplet_root = droplet_root end - # Adds a +javaagent+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to + # Adds a +javaagent+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to # ensure that the path is always accurate. # # @param [Pathname] path the path to the +javaagent+ JAR @@ -43,7 +43,17 @@ def add_javaagent(path) self end - # Adds a system property to the +JAVA_OPTS+. Ensures that the key is prepended with +-D+. If the value is a + # Adds a +bootclasspath/p+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to + # ensure that the path is always accurate. + # + # @param [Pathname] path the path to the +javaagent+ JAR + # @return [JavaOpts] +self+ for chaining + def add_bootclasspath_p(path) + self << "-Xbootclasspath/p:#{qualify_path path}" + self + end + + # Adds a system property to the +JAVA_OPTS+. Ensures that the key is prepended with +-D+. If the value is a # +Pathname+, then prepends +$PWD+ to the path (relative to the droplet root) to ensure that the path is always # accurate. Otherwise, uses the value as-is. # @@ -55,7 +65,7 @@ def add_system_property(key, value) self end - # Adds an option to the +JAVA_OPTS+. Nothing is prepended to the key. If the value is a +Pathname+, then + # Adds an option to the +JAVA_OPTS+. Nothing is prepended to the key. If the value is a +Pathname+, then # prepends +$PWD+ to the path (relative to the droplet root) to ensure that the path is always accurate. # Otherwise, uses the value as-is. # diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb new file mode 100644 index 0000000000..12f5ea3566 --- /dev/null +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -0,0 +1,62 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch JRebel support. + class JrebelAgent < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_zip false + FileUtils.mv(download_location + 'jrebel.jar', @droplet.sandbox + jar_name) + FileUtils.remove_dir(download_location, true) + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts + .add_javaagent(@droplet.sandbox + jar_name) + .add_bootclasspath_p(@droplet.sandbox + jar_name) + .add_system_property('rebel.remoting_plugin', true) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + jrebel_configured?(@application.root) || jrebel_configured?(@application.root + 'WEB-INF/classes') + end + + private + + def jrebel_configured?(root_path) + (root_path + 'rebel.xml').exist? && (root_path + 'rebel-remote.xml').exist? + end + + def download_location + @droplet.sandbox + 'jrebel' + end + + end + + end +end diff --git a/spec/fixtures/framework_jrebel_app/rebel-remote.xml b/spec/fixtures/framework_jrebel_app/rebel-remote.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_jrebel_app/rebel.xml b/spec/fixtures/framework_jrebel_app/rebel.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/stub-jrebel-archive.zip b/spec/fixtures/stub-jrebel-archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..46a4a8779b27a25a1111648450544a4561f9de00 GIT binary patch literal 480 zcmWIWW@h1H0D-9mZf;-(lwfBNV8|*;O-jwt4~^hqcy#hg$S)xN$|%AR0MsPHzyXB) zQ7$N&1QD7bdiAmri$L1D+3$taF#VOG_Y7mMo84eI?I&W z{=M_%|JpU-m}q>S`@MmVHwB(xfO!`y-)O=jmVERH3K$%O$2% z>hP5}{;u-f5(oPp?6>&3$@l`7_y%Q(nJy9ma}TyWVGn6|q+GK0#Iddg8JmwjoX?OS zX4cW_!?V@lmq3Im(BteJ`}nw2b^*gEl#v0*XJis(#ua`%u;6rf>j+}PLz4p@nh*mJ oVTo+GAOpgHC5@&C1CT?O10J#g-mGjOTbO{b2T0oi-N(QH08-7H@c;k- literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb new file mode 100644 index 0000000000..f4583c4f9d --- /dev/null +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -0,0 +1,55 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/jrebel_agent' + +describe JavaBuildpack::Framework::JrebelAgent do + include_context 'component_helper' + + it 'does not detect without JRebel config files present' do + expect(component.detect).to be_nil + end + + it 'detects with JRebel config files are present', + app_fixture: 'framework_jrebel_app', + cache_fixture: 'stub-jrebel-archive.zip' do + expect(component.detect).to eq("jrebel-agent=#{version}") + end + + it 'downloads JRebel agent JAR', + app_fixture: 'framework_jrebel_app', + cache_fixture: 'stub-jrebel-archive.zip' do + + component.compile + + expect(sandbox + "jrebel_agent-#{version}.jar").to exist + end + + it 'updates JAVA_OPTS', + app_fixture: 'framework_jrebel_app', + cache_fixture: 'stub-jrebel-archive.zip' do + allow(services).to receive(:find_service).and_return('credentials' => { 'licenseKey' => 'test-license-key' }) + + component.release + + expect(java_opts).to include("-javaagent:$PWD/.java-buildpack/jrebel_agent/jrebel_agent-#{version}.jar") + expect(java_opts).to include('-Drebel.remoting_plugin=true') + expect(java_opts).to include("-Xbootclasspath/p:$PWD/.java-buildpack/jrebel_agent/jrebel_agent-#{version}.jar") + end + +end From 634b666c497f674db833491cd3fa184d2e661f53 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 18 Feb 2015 11:24:05 +0000 Subject: [PATCH 004/812] Updates the copyright statements dates All file now read 2013-2015 where they previously stated only 2013 or 2013-2014. The Contibuting documentation is also updated to request that new files contain 2015 instead of 2014 as was previously stated. A template exists in InteliJ to provide an Apache license header to all new Ruby files with the current year. [#86992848] --- CONTRIBUTING.md | 8 ++++---- NOTICE | 2 +- Rakefile | 2 +- bin/compile | 2 +- bin/detect | 2 +- bin/release | 2 +- config/app_dynamics_agent.yml | 2 +- config/cache.yml | 2 +- config/components.yml | 2 +- config/groovy.yml | 2 +- config/java_opts.yml | 2 +- config/jrebel_agent.yml | 2 +- config/logging.yml | 2 +- config/maria_db_jdbc.yml | 2 +- config/new_relic_agent.yml | 2 +- config/open_jdk_jre.yml | 2 +- config/oracle_jre.yml | 2 +- config/play_framework_auto_reconfiguration.yml | 2 +- config/play_framework_jpa_plugin.yml | 2 +- config/postgresql_jdbc.yml | 2 +- config/repository.yml | 2 +- config/spring_auto_reconfiguration.yml | 2 +- config/spring_boot_cli.yml | 2 +- config/tomcat.yml | 2 +- lib/java_buildpack.rb | 2 +- lib/java_buildpack/buildpack.rb | 2 +- lib/java_buildpack/component.rb | 2 +- lib/java_buildpack/component/additional_libraries.rb | 2 +- lib/java_buildpack/component/application.rb | 2 +- lib/java_buildpack/component/base_component.rb | 2 +- lib/java_buildpack/component/droplet.rb | 2 +- lib/java_buildpack/component/immutable_java_home.rb | 2 +- lib/java_buildpack/component/java_opts.rb | 2 +- lib/java_buildpack/component/modular_component.rb | 2 +- lib/java_buildpack/component/mutable_java_home.rb | 2 +- lib/java_buildpack/component/services.rb | 2 +- .../component/versioned_dependency_component.rb | 2 +- lib/java_buildpack/container.rb | 2 +- lib/java_buildpack/container/dist_zip.rb | 2 +- lib/java_buildpack/container/dist_zip_like.rb | 2 +- lib/java_buildpack/container/groovy.rb | 2 +- lib/java_buildpack/container/java_main.rb | 2 +- lib/java_buildpack/container/play_framework.rb | 2 +- lib/java_buildpack/container/ratpack.rb | 2 +- lib/java_buildpack/container/spring_boot.rb | 2 +- lib/java_buildpack/container/tomcat.rb | 2 +- lib/java_buildpack/container/tomcat/gemfire/gemfire.rb | 2 +- .../container/tomcat/gemfire/gemfire_logging.rb | 2 +- .../container/tomcat/gemfire/gemfire_logging_api.rb | 2 +- .../container/tomcat/gemfire/gemfire_modules.rb | 2 +- .../container/tomcat/gemfire/gemfire_modules_tomcat7.rb | 2 +- .../container/tomcat/gemfire/gemfire_security.rb | 2 +- .../container/tomcat/tomcat_access_logging_support.rb | 2 +- .../container/tomcat/tomcat_gemfire_store.rb | 2 +- .../container/tomcat/tomcat_insight_support.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_instance.rb | 2 +- .../container/tomcat/tomcat_lifecycle_support.rb | 2 +- .../container/tomcat/tomcat_logging_support.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_redis_store.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_utils.rb | 2 +- lib/java_buildpack/framework.rb | 2 +- lib/java_buildpack/framework/app_dynamics_agent.rb | 2 +- lib/java_buildpack/framework/java_opts.rb | 2 +- lib/java_buildpack/framework/jrebel_agent.rb | 2 +- lib/java_buildpack/framework/maria_db_jdbc.rb | 2 +- lib/java_buildpack/framework/new_relic_agent.rb | 2 +- .../framework/play_framework_auto_reconfiguration.rb | 2 +- lib/java_buildpack/framework/play_framework_jpa_plugin.rb | 2 +- lib/java_buildpack/framework/postgresql_jdbc.rb | 2 +- .../framework/spring_auto_reconfiguration.rb | 2 +- .../spring_auto_reconfiguration/web_xml_modifier.rb | 2 +- lib/java_buildpack/framework/spring_insight.rb | 2 +- lib/java_buildpack/jre.rb | 2 +- lib/java_buildpack/jre/memory/memory_bucket.rb | 2 +- lib/java_buildpack/jre/memory/memory_limit.rb | 2 +- lib/java_buildpack/jre/memory/memory_size.rb | 2 +- .../jre/memory/openjdk_memory_heuristic_factory.rb | 2 +- lib/java_buildpack/jre/memory/stack_memory_bucket.rb | 2 +- .../jre/memory/weight_balancing_memory_heuristic.rb | 2 +- lib/java_buildpack/jre/open_jdk_jre.rb | 2 +- lib/java_buildpack/jre/open_jdk_like.rb | 2 +- lib/java_buildpack/jre/oracle_jre.rb | 2 +- lib/java_buildpack/logging.rb | 2 +- lib/java_buildpack/repository.rb | 2 +- lib/java_buildpack/repository/configured_item.rb | 2 +- lib/java_buildpack/repository/repository_index.rb | 2 +- lib/java_buildpack/repository/version_resolver.rb | 2 +- lib/java_buildpack/util.rb | 2 +- lib/java_buildpack/util/cache.rb | 2 +- lib/java_buildpack/util/cache/application_cache.rb | 2 +- lib/java_buildpack/util/cache/download_cache.rb | 2 +- lib/java_buildpack/util/cache/inferred_network_failure.rb | 2 +- lib/java_buildpack/util/class_file_utils.rb | 2 +- lib/java_buildpack/util/configuration_utils.rb | 2 +- lib/java_buildpack/util/constantize.rb | 2 +- lib/java_buildpack/util/dash_case.rb | 2 +- lib/java_buildpack/util/file_enumerable.rb | 2 +- lib/java_buildpack/util/find_single_directory.rb | 2 +- lib/java_buildpack/util/format_duration.rb | 2 +- lib/java_buildpack/util/groovy_utils.rb | 2 +- lib/java_buildpack/util/jar_finder.rb | 2 +- lib/java_buildpack/util/play.rb | 2 +- lib/java_buildpack/util/properties.rb | 2 +- lib/java_buildpack/util/qualify_path.rb | 2 +- lib/java_buildpack/util/ratpack_utils.rb | 2 +- lib/java_buildpack/util/shell.rb | 2 +- lib/java_buildpack/util/snake_case.rb | 2 +- lib/java_buildpack/util/space_case.rb | 2 +- lib/java_buildpack/util/spring_boot_utils.rb | 2 +- lib/java_buildpack/util/start_script.rb | 2 +- lib/java_buildpack/util/tokenized_version.rb | 2 +- resources/tomcat/conf/context.xml | 2 +- spec/application_helper.rb | 2 +- spec/bin/compile_spec.rb | 2 +- spec/bin/detect_spec.rb | 2 +- spec/bin/release_spec.rb | 2 +- spec/component_helper.rb | 2 +- spec/console_helper.rb | 2 +- spec/droplet_helper.rb | 2 +- spec/fixtures/container_groovy_main_method/Alpha.groovy | 2 +- .../container_groovy_main_method/Application.groovy | 2 +- .../container_groovy_main_method/directory/Beta.groovy | 2 +- spec/fixtures/container_groovy_non_pogo/Alpha.groovy | 2 +- .../fixtures/container_groovy_non_pogo/Application.groovy | 2 +- .../logback.groovy | 2 +- spec/fixtures/container_groovy_shebang/Alpha.groovy | 2 +- spec/fixtures/container_groovy_shebang/Application.groovy | 2 +- .../Application.groovy | 2 +- .../container_groovy_with_jars/Application.groovy | 2 +- .../.java-buildpack/tomcat/conf/context.xml | 2 +- .../container_tomcat_gemfire_store_context_after.xml | 2 +- .../.java-buildpack/tomcat/conf/context.xml | 2 +- .../container_tomcat_redis_store_context_after.xml | 2 +- .../lib/java_buildpack/container/long_detect_tags.rb | 2 +- spec/integration_helper.rb | 2 +- spec/internet_availability_helper.rb | 2 +- spec/java_buildpack/buildpack_spec.rb | 2 +- .../java_buildpack/component/additional_libraries_spec.rb | 2 +- spec/java_buildpack/component/application_spec.rb | 2 +- spec/java_buildpack/component/base_component_spec.rb | 2 +- spec/java_buildpack/component/droplet_spec.rb | 2 +- spec/java_buildpack/component/immutable_java_home_spec.rb | 2 +- spec/java_buildpack/component/java_opts_spec.rb | 2 +- spec/java_buildpack/component/modular_component_spec.rb | 2 +- spec/java_buildpack/component/mutable_java_home_spec.rb | 2 +- spec/java_buildpack/component/services_spec.rb | 2 +- .../component/versioned_dependency_component_spec.rb | 2 +- spec/java_buildpack/container/dist_zip_like_spec.rb | 2 +- spec/java_buildpack/container/dist_zip_spec.rb | 2 +- spec/java_buildpack/container/groovy_spec.rb | 2 +- spec/java_buildpack/container/java_main_spec.rb | 2 +- spec/java_buildpack/container/play_framework_spec.rb | 2 +- spec/java_buildpack/container/ratpack_spec.rb | 2 +- spec/java_buildpack/container/spring_boot_cli_spec.rb | 2 +- spec/java_buildpack/container/spring_boot_spec.rb | 2 +- .../container/tomcat/gemfire/gemfire_logging_api_spec.rb | 2 +- .../container/tomcat/gemfire/gemfire_logging_spec.rb | 2 +- .../container/tomcat/gemfire/gemfire_modules_spec.rb | 2 +- .../tomcat/gemfire/gemfire_modules_tomcat7_spec.rb | 2 +- .../container/tomcat/gemfire/gemfire_security_spec.rb | 2 +- .../container/tomcat/gemfire/gemfire_spec.rb | 2 +- .../tomcat/tomcat_access_logging_support_spec.rb | 2 +- .../container/tomcat/tomcat_gemfire_store_spec.rb | 2 +- .../container/tomcat/tomcat_insight_support_spec.rb | 2 +- .../container/tomcat/tomcat_instance_spec.rb | 2 +- .../container/tomcat/tomcat_lifecycle_support_spec.rb | 2 +- .../container/tomcat/tomcat_logging_support_spec.rb | 2 +- .../container/tomcat/tomcat_redis_store_spec.rb | 2 +- spec/java_buildpack/container/tomcat_spec.rb | 2 +- spec/java_buildpack/framework/app_dynamics_agent_spec.rb | 2 +- spec/java_buildpack/framework/java_opts_spec.rb | 2 +- spec/java_buildpack/framework/jrebel_agent_spec.rb | 2 +- spec/java_buildpack/framework/maria_db_jdbc_spec.rb | 2 +- spec/java_buildpack/framework/new_relic_agent_spec.rb | 2 +- .../framework/play_framework_auto_reconfiguration_spec.rb | 2 +- .../framework/play_framework_jpa_plugin_spec.rb | 2 +- spec/java_buildpack/framework/postgresql_jdbc_spec.rb | 2 +- .../spring_auto_reconfiguration/web_xml_modifier_spec.rb | 2 +- .../framework/spring_auto_reconfiguration_spec.rb | 2 +- spec/java_buildpack/framework/spring_insight_spec.rb | 2 +- spec/java_buildpack/jre/memory/memory_bucket_spec.rb | 2 +- spec/java_buildpack/jre/memory/memory_limit_spec.rb | 2 +- spec/java_buildpack/jre/memory/memory_range_spec.rb | 2 +- spec/java_buildpack/jre/memory/memory_size_spec.rb | 2 +- .../java_buildpack/jre/memory/stack_memory_bucket_spec.rb | 2 +- .../jre/memory/weight_balancing_memory_heuristic_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_jre_spec.rb | 2 +- spec/java_buildpack/jre/oracle_jre_spec.rb | 2 +- spec/java_buildpack/logging/delegating_logger_spec.rb | 2 +- spec/java_buildpack/repository/configured_item_spec.rb | 2 +- spec/java_buildpack/repository/repository_index_spec.rb | 2 +- spec/java_buildpack/repository/version_resolver_spec.rb | 2 +- spec/java_buildpack/util/cache/application_cache_spec.rb | 2 +- spec/java_buildpack/util/cache/cached_file_spec.rb | 2 +- spec/java_buildpack/util/cache/download_cache_spec.rb | 2 +- .../util/cache/internet_availability_spec.rb | 2 +- spec/java_buildpack/util/cache/yield_file_with_content.rb | 2 +- spec/java_buildpack/util/constantize_spec.rb | 2 +- spec/java_buildpack/util/format_duration_spec.rb | 2 +- spec/java_buildpack/util/play/base_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_spec.rb | 2 +- spec/java_buildpack/util/properties_spec.rb | 2 +- spec/java_buildpack/util/shell_spec.rb | 2 +- spec/java_buildpack/util/tokenized_version_spec.rb | 2 +- spec/logging_helper.rb | 2 +- spec/memory_limit_helper.rb | 2 +- spec/spec_helper.rb | 2 +- 207 files changed, 210 insertions(+), 210 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 75a843f580..0c68262a77 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ Please carefully follow the whitespace and formatting conventions already presen ## Add Apache license header to all new classes ```ruby # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -58,16 +58,16 @@ Please carefully follow the whitespace and formatting conventions already presen require ...; ``` ## Update Apache license header to modified files as necessary -Always check the date range in the license header. For example, if you've modified a file in 2014 whose header still reads +Always check the date range in the license header. For example, if you've modified a file in 2015 whose header still reads ```ruby # Copyright 2013 the original author or authors. ``` -then be sure to update it to 2014 appropriately +then be sure to update it to 2015 appropriately ```ruby - # Copyright 2013-2014 the original author or authors. + # Copyright 2013-2015 the original author or authors. ``` ## Submit RSpec test cases for all behavior changes diff --git a/NOTICE b/NOTICE index 8d3e4c02a9..dbc862fe65 100644 --- a/NOTICE +++ b/NOTICE @@ -1,2 +1,2 @@ Cloud Foundry Java Buildpack - Copyright 2013 the original author or authors. + Copyright 2013-2015 the original author or authors. diff --git a/Rakefile b/Rakefile index 899e4bc7a6..2c7eadfa3f 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/compile b/bin/compile index 1d74294fa6..53e0b8d530 100755 --- a/bin/compile +++ b/bin/compile @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/detect b/bin/detect index 0af538a042..df914f7150 100755 --- a/bin/detect +++ b/bin/detect @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/release b/bin/release index eeecd019af..afc14c8ba4 100755 --- a/bin/release +++ b/bin/release @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index b39b66152f..ecab0ff267 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/cache.yml b/config/cache.yml index 61b451bf13..9b9c8ba6ad 100644 --- a/config/cache.yml +++ b/config/cache.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/components.yml b/config/components.yml index 18b0f10732..a24db3b07f 100644 --- a/config/components.yml +++ b/config/components.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/groovy.yml b/config/groovy.yml index d552d29e40..6ec9823ef5 100644 --- a/config/groovy.yml +++ b/config/groovy.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/java_opts.yml b/config/java_opts.yml index 1de33db86e..92faa2e361 100644 --- a/config/java_opts.yml +++ b/config/java_opts.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2014 the original author or authors. +# Copyright 2014-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml index c676f7b7cf..31aa9e5369 100644 --- a/config/jrebel_agent.yml +++ b/config/jrebel_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/logging.yml b/config/logging.yml index eb83017b59..bdd017df62 100644 --- a/config/logging.yml +++ b/config/logging.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/maria_db_jdbc.yml b/config/maria_db_jdbc.yml index d294543c03..77f03d7c0c 100644 --- a/config/maria_db_jdbc.yml +++ b/config/maria_db_jdbc.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/new_relic_agent.yml b/config/new_relic_agent.yml index c87e0e6b8f..e0237c7326 100644 --- a/config/new_relic_agent.yml +++ b/config/new_relic_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 2a4feb2af6..6f83d929fe 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index cdb6226dc2..e4d46efc82 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/play_framework_auto_reconfiguration.yml b/config/play_framework_auto_reconfiguration.yml index feb522ce83..63dd0935b3 100644 --- a/config/play_framework_auto_reconfiguration.yml +++ b/config/play_framework_auto_reconfiguration.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/play_framework_jpa_plugin.yml b/config/play_framework_jpa_plugin.yml index 876dba0f99..1c6df17637 100644 --- a/config/play_framework_jpa_plugin.yml +++ b/config/play_framework_jpa_plugin.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/postgresql_jdbc.yml b/config/postgresql_jdbc.yml index 96d7960863..6937a54a65 100644 --- a/config/postgresql_jdbc.yml +++ b/config/postgresql_jdbc.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/repository.yml b/config/repository.yml index ab4c37a2fe..daca398bfe 100644 --- a/config/repository.yml +++ b/config/repository.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/spring_auto_reconfiguration.yml b/config/spring_auto_reconfiguration.yml index 5b88fbfa9c..128dfc4d16 100644 --- a/config/spring_auto_reconfiguration.yml +++ b/config/spring_auto_reconfiguration.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/spring_boot_cli.yml b/config/spring_boot_cli.yml index c7eb15327f..c1748bb922 100644 --- a/config/spring_boot_cli.yml +++ b/config/spring_boot_cli.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/tomcat.yml b/config/tomcat.yml index 1a5e5c3c6a..1a4471da13 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack.rb b/lib/java_buildpack.rb index fe2c1860bf..a73a7d606c 100644 --- a/lib/java_buildpack.rb +++ b/lib/java_buildpack.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 0250d9fbbf..229afa39aa 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component.rb b/lib/java_buildpack/component.rb index 353f67c5f4..2fd75e9aac 100644 --- a/lib/java_buildpack/component.rb +++ b/lib/java_buildpack/component.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/additional_libraries.rb b/lib/java_buildpack/component/additional_libraries.rb index 567a252951..061132135d 100644 --- a/lib/java_buildpack/component/additional_libraries.rb +++ b/lib/java_buildpack/component/additional_libraries.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index cb3428e3f8..d483d5d644 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index f73292ac1b..7617382512 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index cb5512e746..0c594b9350 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index 3218731b4b..830e423582 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index d259c34b53..cca1517fee 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/modular_component.rb b/lib/java_buildpack/component/modular_component.rb index e19d602fd7..f10f3ac5c9 100644 --- a/lib/java_buildpack/component/modular_component.rb +++ b/lib/java_buildpack/component/modular_component.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index 03c8ecf804..8c8d575c3a 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/services.rb b/lib/java_buildpack/component/services.rb index 943f1e6e6f..dd3e8b5e33 100644 --- a/lib/java_buildpack/component/services.rb +++ b/lib/java_buildpack/component/services.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/versioned_dependency_component.rb b/lib/java_buildpack/component/versioned_dependency_component.rb index dc2e58eb40..792d0ab777 100644 --- a/lib/java_buildpack/component/versioned_dependency_component.rb +++ b/lib/java_buildpack/component/versioned_dependency_component.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container.rb b/lib/java_buildpack/container.rb index 6a3fcff59b..4816a649af 100644 --- a/lib/java_buildpack/container.rb +++ b/lib/java_buildpack/container.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/dist_zip.rb b/lib/java_buildpack/container/dist_zip.rb index f455733104..8d11898a9b 100644 --- a/lib/java_buildpack/container/dist_zip.rb +++ b/lib/java_buildpack/container/dist_zip.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 7ded68752d..ba695db434 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index dbe8d9eb48..9e16c6050e 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index 3811992091..55108445e7 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/play_framework.rb b/lib/java_buildpack/container/play_framework.rb index 18679a4aa9..c012f3ddb3 100644 --- a/lib/java_buildpack/container/play_framework.rb +++ b/lib/java_buildpack/container/play_framework.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/ratpack.rb b/lib/java_buildpack/container/ratpack.rb index b065e0dccb..4ce3d5c41d 100644 --- a/lib/java_buildpack/container/ratpack.rb +++ b/lib/java_buildpack/container/ratpack.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/spring_boot.rb b/lib/java_buildpack/container/spring_boot.rb index 3695bcb312..ea8ec2660b 100644 --- a/lib/java_buildpack/container/spring_boot.rb +++ b/lib/java_buildpack/container/spring_boot.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 8b07276b5e..9f9d56d1c9 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb index c4780176e3..16a5e41dba 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb index b9c2298d02..1dd89cfc9f 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb index bbf50a0cec..2276ede9d5 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb index 1a55ae08d4..1cd627fd04 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb index b851e94f4a..2e6d04f6a0 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb index 341c72995c..787b91901a 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb index 303afecfd2..adff3ed313 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb b/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb index 2a728600b6..7a5ee1ed9e 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb index 35aec690af..4379eb75d9 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index d16abbec0e..181ffbbe2a 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb index 66cd8c94a7..c4c34e9fe3 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb index 2680a61ce4..2b463bd669 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb index 5ecc1b5ca0..8b24bdc123 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_utils.rb b/lib/java_buildpack/container/tomcat/tomcat_utils.rb index f322e9616b..a7792e8f26 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_utils.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_utils.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework.rb b/lib/java_buildpack/framework.rb index 648f5b193b..9754249ebc 100644 --- a/lib/java_buildpack/framework.rb +++ b/lib/java_buildpack/framework.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index fe4fa5e361..dcb90becef 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index f9ba928e80..cc0077c251 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index 12f5ea3566..36eb543162 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/maria_db_jdbc.rb b/lib/java_buildpack/framework/maria_db_jdbc.rb index 4e336b0117..991a05cf3d 100644 --- a/lib/java_buildpack/framework/maria_db_jdbc.rb +++ b/lib/java_buildpack/framework/maria_db_jdbc.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 6f4a7a8e95..ad3405168e 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb b/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb index f2768ec231..7a42ecdb23 100644 --- a/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/play_framework_jpa_plugin.rb b/lib/java_buildpack/framework/play_framework_jpa_plugin.rb index 272d444dc5..e8468dd0db 100644 --- a/lib/java_buildpack/framework/play_framework_jpa_plugin.rb +++ b/lib/java_buildpack/framework/play_framework_jpa_plugin.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/postgresql_jdbc.rb b/lib/java_buildpack/framework/postgresql_jdbc.rb index d0bf03b59c..01df9f90b1 100644 --- a/lib/java_buildpack/framework/postgresql_jdbc.rb +++ b/lib/java_buildpack/framework/postgresql_jdbc.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 68e9a4c823..371e5e088f 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb index 4fbf029924..4099bd0947 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/spring_insight.rb b/lib/java_buildpack/framework/spring_insight.rb index f8377cdad4..1d841c380a 100644 --- a/lib/java_buildpack/framework/spring_insight.rb +++ b/lib/java_buildpack/framework/spring_insight.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre.rb b/lib/java_buildpack/jre.rb index 189f0b6929..2755501294 100644 --- a/lib/java_buildpack/jre.rb +++ b/lib/java_buildpack/jre.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/memory/memory_bucket.rb b/lib/java_buildpack/jre/memory/memory_bucket.rb index db909efbda..dde34aae2a 100644 --- a/lib/java_buildpack/jre/memory/memory_bucket.rb +++ b/lib/java_buildpack/jre/memory/memory_bucket.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/memory/memory_limit.rb b/lib/java_buildpack/jre/memory/memory_limit.rb index afc26c75f2..9e4f3e98de 100644 --- a/lib/java_buildpack/jre/memory/memory_limit.rb +++ b/lib/java_buildpack/jre/memory/memory_limit.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/memory/memory_size.rb b/lib/java_buildpack/jre/memory/memory_size.rb index 0571a0ce74..75ed8207ba 100644 --- a/lib/java_buildpack/jre/memory/memory_size.rb +++ b/lib/java_buildpack/jre/memory/memory_size.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/memory/openjdk_memory_heuristic_factory.rb b/lib/java_buildpack/jre/memory/openjdk_memory_heuristic_factory.rb index 69e6271802..e36017a734 100644 --- a/lib/java_buildpack/jre/memory/openjdk_memory_heuristic_factory.rb +++ b/lib/java_buildpack/jre/memory/openjdk_memory_heuristic_factory.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/memory/stack_memory_bucket.rb b/lib/java_buildpack/jre/memory/stack_memory_bucket.rb index f3935cbaa6..f6bf8fd148 100644 --- a/lib/java_buildpack/jre/memory/stack_memory_bucket.rb +++ b/lib/java_buildpack/jre/memory/stack_memory_bucket.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb b/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb index f769131b31..3ee50f793c 100644 --- a/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb +++ b/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_jre.rb b/lib/java_buildpack/jre/open_jdk_jre.rb index 34e8b82c21..7c648def53 100644 --- a/lib/java_buildpack/jre/open_jdk_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_jre.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like.rb b/lib/java_buildpack/jre/open_jdk_like.rb index 4b665c02b6..b9862da1fc 100644 --- a/lib/java_buildpack/jre/open_jdk_like.rb +++ b/lib/java_buildpack/jre/open_jdk_like.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/oracle_jre.rb b/lib/java_buildpack/jre/oracle_jre.rb index 849030062f..f0f2f56b20 100644 --- a/lib/java_buildpack/jre/oracle_jre.rb +++ b/lib/java_buildpack/jre/oracle_jre.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/logging.rb b/lib/java_buildpack/logging.rb index 512914f693..db0b320bd7 100644 --- a/lib/java_buildpack/logging.rb +++ b/lib/java_buildpack/logging.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository.rb b/lib/java_buildpack/repository.rb index dd5cef100b..27c9808c24 100644 --- a/lib/java_buildpack/repository.rb +++ b/lib/java_buildpack/repository.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/configured_item.rb b/lib/java_buildpack/repository/configured_item.rb index 9bd6b413b6..f5674d5d33 100644 --- a/lib/java_buildpack/repository/configured_item.rb +++ b/lib/java_buildpack/repository/configured_item.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 62e0118446..1c764668c4 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/version_resolver.rb b/lib/java_buildpack/repository/version_resolver.rb index 61d4872673..4a72cf642b 100644 --- a/lib/java_buildpack/repository/version_resolver.rb +++ b/lib/java_buildpack/repository/version_resolver.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util.rb b/lib/java_buildpack/util.rb index 3439a66f9d..de70b450fe 100644 --- a/lib/java_buildpack/util.rb +++ b/lib/java_buildpack/util.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache.rb b/lib/java_buildpack/util/cache.rb index 700d23830e..b1820c4f84 100644 --- a/lib/java_buildpack/util/cache.rb +++ b/lib/java_buildpack/util/cache.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/application_cache.rb b/lib/java_buildpack/util/cache/application_cache.rb index aa9c4aa541..e398189a03 100644 --- a/lib/java_buildpack/util/cache/application_cache.rb +++ b/lib/java_buildpack/util/cache/application_cache.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 1bda3625b9..fb56c9cd8f 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/inferred_network_failure.rb b/lib/java_buildpack/util/cache/inferred_network_failure.rb index 72af10eb81..407a363cef 100644 --- a/lib/java_buildpack/util/cache/inferred_network_failure.rb +++ b/lib/java_buildpack/util/cache/inferred_network_failure.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/class_file_utils.rb b/lib/java_buildpack/util/class_file_utils.rb index aa17c8c9d1..b4953f8d52 100644 --- a/lib/java_buildpack/util/class_file_utils.rb +++ b/lib/java_buildpack/util/class_file_utils.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 83ddaf54d0..e3c7cad692 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/constantize.rb b/lib/java_buildpack/util/constantize.rb index b0c2aa292f..649b526bc8 100644 --- a/lib/java_buildpack/util/constantize.rb +++ b/lib/java_buildpack/util/constantize.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/dash_case.rb b/lib/java_buildpack/util/dash_case.rb index 0c662fd475..43eb5c4d11 100644 --- a/lib/java_buildpack/util/dash_case.rb +++ b/lib/java_buildpack/util/dash_case.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/file_enumerable.rb b/lib/java_buildpack/util/file_enumerable.rb index 0a4b02f7b2..71f2cbd01d 100644 --- a/lib/java_buildpack/util/file_enumerable.rb +++ b/lib/java_buildpack/util/file_enumerable.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/find_single_directory.rb b/lib/java_buildpack/util/find_single_directory.rb index 795d772741..76b75d4158 100644 --- a/lib/java_buildpack/util/find_single_directory.rb +++ b/lib/java_buildpack/util/find_single_directory.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/format_duration.rb b/lib/java_buildpack/util/format_duration.rb index e2b8ee7ce4..820f6816b8 100644 --- a/lib/java_buildpack/util/format_duration.rb +++ b/lib/java_buildpack/util/format_duration.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/groovy_utils.rb b/lib/java_buildpack/util/groovy_utils.rb index 6d04b899a0..411fc9d7ea 100644 --- a/lib/java_buildpack/util/groovy_utils.rb +++ b/lib/java_buildpack/util/groovy_utils.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/jar_finder.rb b/lib/java_buildpack/util/jar_finder.rb index 7e2ea914d9..97a7dbd5a7 100644 --- a/lib/java_buildpack/util/jar_finder.rb +++ b/lib/java_buildpack/util/jar_finder.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play.rb b/lib/java_buildpack/util/play.rb index ce53ade7e9..37eb3bca4e 100644 --- a/lib/java_buildpack/util/play.rb +++ b/lib/java_buildpack/util/play.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/properties.rb b/lib/java_buildpack/util/properties.rb index b78ba6de8b..223a4ebdce 100644 --- a/lib/java_buildpack/util/properties.rb +++ b/lib/java_buildpack/util/properties.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/qualify_path.rb b/lib/java_buildpack/util/qualify_path.rb index 06bed2d946..2a1814e504 100644 --- a/lib/java_buildpack/util/qualify_path.rb +++ b/lib/java_buildpack/util/qualify_path.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/ratpack_utils.rb b/lib/java_buildpack/util/ratpack_utils.rb index acb88286b3..5acb9e1126 100644 --- a/lib/java_buildpack/util/ratpack_utils.rb +++ b/lib/java_buildpack/util/ratpack_utils.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/shell.rb b/lib/java_buildpack/util/shell.rb index 9be88eb00f..924de030d4 100644 --- a/lib/java_buildpack/util/shell.rb +++ b/lib/java_buildpack/util/shell.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/snake_case.rb b/lib/java_buildpack/util/snake_case.rb index eb185318c1..5a5f46aa37 100644 --- a/lib/java_buildpack/util/snake_case.rb +++ b/lib/java_buildpack/util/snake_case.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/space_case.rb b/lib/java_buildpack/util/space_case.rb index d6a60838c3..e4b6015e65 100644 --- a/lib/java_buildpack/util/space_case.rb +++ b/lib/java_buildpack/util/space_case.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/spring_boot_utils.rb b/lib/java_buildpack/util/spring_boot_utils.rb index a793b7f01b..243497ca3f 100644 --- a/lib/java_buildpack/util/spring_boot_utils.rb +++ b/lib/java_buildpack/util/spring_boot_utils.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/start_script.rb b/lib/java_buildpack/util/start_script.rb index 354b3ec73b..9d79786a00 100644 --- a/lib/java_buildpack/util/start_script.rb +++ b/lib/java_buildpack/util/start_script.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index 9d6f076db9..ef6aa77510 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # Cloud Foundry Java Buildpack -# Copyright 2013 the original author or authors. +# Copyright 2013-2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/resources/tomcat/conf/context.xml b/resources/tomcat/conf/context.xml index 7e3cf282f6..37fa92cf6f 100644 --- a/resources/tomcat/conf/context.xml +++ b/resources/tomcat/conf/context.xml @@ -1,6 +1,6 @@ - + From e89e54697fe6f0a694ac78102321f7fc49830ffa Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Mon, 2 Mar 2015 11:15:31 +0000 Subject: [PATCH 015/812] Update GemFire log messages This commit updates the console messages output by the buildpack when downloading GemFire components to better match GemFire naming convention. --- lib/java_buildpack/container/tomcat/gemfire/gemfire.rb | 2 +- lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb | 2 +- .../container/tomcat/gemfire/gemfire_logging_api.rb | 2 +- lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb | 2 +- .../container/tomcat/gemfire/gemfire_modules_tomcat7.rb | 2 +- lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb index 16a5e41dba..2ae762ce3a 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb @@ -28,7 +28,7 @@ class GemFire < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_jar(jar_name, tomcat_lib) + download_jar(jar_name, tomcat_lib, 'GemFire') end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb index 1dd89cfc9f..c8fd237995 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb @@ -28,7 +28,7 @@ class GemFireLogging < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_jar(jar_name, tomcat_lib) + download_jar(jar_name, tomcat_lib, 'GemFire Logging') end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb index 2276ede9d5..15ba15f015 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb @@ -28,7 +28,7 @@ class GemFireLoggingApi < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_jar(jar_name, tomcat_lib) + download_jar(jar_name, tomcat_lib, 'GemFire Logging API') end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb index 1cd627fd04..97bb6904ba 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb @@ -28,7 +28,7 @@ class GemFireModules < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_jar(jar_name, tomcat_lib) + download_jar(jar_name, tomcat_lib, 'GemFire Modules') end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb index 2e6d04f6a0..922e2f6c1c 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb @@ -28,7 +28,7 @@ class GemFireModulesTomcat7 < JavaBuildpack::Component::VersionedDependencyCompo # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_jar(jar_name, tomcat_lib) + download_jar(jar_name, tomcat_lib, 'GemFire Modules Tomcat7') end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb index 787b91901a..35e9facfa6 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb @@ -28,7 +28,7 @@ class GemFireSecurity < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_jar(jar_name, tomcat_lib) + download_jar(jar_name, tomcat_lib, 'GemFire Security') end # (see JavaBuildpack::Component::BaseComponent#release) From 623c428ed4b8fd411b2368235aa3896e0eef4984 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 5 Mar 2015 11:17:47 +0000 Subject: [PATCH 016/812] Ignore Logback related Groovy files When detecting which container should run an application the Spring Boot CLI container should not trigger on Groovy files located within Logback. [#84676024] --- .../container/spring_boot_cli.rb | 6 +++++- .../container_groovy_logback/Alpha.java | 18 ++++++++++++++++++ .../ch/qos/logback/pogo.groovy | 5 +++++ .../container/spring_boot_cli_spec.rb | 6 ++++++ 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/container_groovy_logback/Alpha.java create mode 100644 spec/fixtures/container_groovy_logback/ch/qos/logback/pogo.groovy diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index 0bd4b9241d..d3842c2b9f 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -60,7 +60,7 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - gf = JavaBuildpack::Util::GroovyUtils.groovy_files(@application) + gf = JavaBuildpack::Util::GroovyUtils.groovy_files(@application).reject { |file| logback_file? file } gf.length > 0 && all_pogo_or_configuration(gf) && no_main_method(gf) && no_shebang(gf) && !web_inf? end @@ -72,6 +72,10 @@ def relative_groovy_files end end + def logback_file?(path) + %r{ch/qos/logback/.*\.groovy$} =~ path.to_s + end + def no_main_method(groovy_files) none?(groovy_files) { |file| JavaBuildpack::Util::GroovyUtils.main_method? file } end diff --git a/spec/fixtures/container_groovy_logback/Alpha.java b/spec/fixtures/container_groovy_logback/Alpha.java new file mode 100644 index 0000000000..affb16604a --- /dev/null +++ b/spec/fixtures/container_groovy_logback/Alpha.java @@ -0,0 +1,18 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Alpha { +} diff --git a/spec/fixtures/container_groovy_logback/ch/qos/logback/pogo.groovy b/spec/fixtures/container_groovy_logback/ch/qos/logback/pogo.groovy new file mode 100644 index 0000000000..02b1a5663b --- /dev/null +++ b/spec/fixtures/container_groovy_logback/ch/qos/logback/pogo.groovy @@ -0,0 +1,5 @@ +package fixtures.container_groovy_logback.ch.qos.logback + +class Directory { + +} \ No newline at end of file diff --git a/spec/java_buildpack/container/spring_boot_cli_spec.rb b/spec/java_buildpack/container/spring_boot_cli_spec.rb index 5f6dced48a..a9b93bd3bf 100644 --- a/spec/java_buildpack/container/spring_boot_cli_spec.rb +++ b/spec/java_buildpack/container/spring_boot_cli_spec.rb @@ -51,6 +51,12 @@ expect(component.detect).to be_nil end + it 'does not detect Logback Groovy files', + app_fixture: 'container_groovy_logback' do + + expect(component.detect).to be_nil + end + it 'does not detect a Groovy file which has a shebang but which also contains a class', app_fixture: 'container_groovy_shebang_containing_class' do From 17162df58ab3dd152cc140e7bb43accd88ea4e1d Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 19 Mar 2015 15:53:49 +0000 Subject: [PATCH 017/812] Configurable AppDynamics application & node names This commit makes it possible to supply values for the AppDynamics application and node names in the configuration and through service credentials. Testing and documentation also updated. [#89413382] --- config/app_dynamics_agent.yml | 1 + docs/framework-app_dynamics_agent.md | 6 ++++ .../framework/app_dynamics_agent.rb | 32 +++++++++++-------- .../framework/app_dynamics_agent_spec.rb | 25 ++++++++++++++- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index ecab0ff267..31ebf790d9 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -17,4 +17,5 @@ --- version: 4.0.+ repository_root: "{default.repository.root}/app-dynamics" +default_node_name: "$(expr \"$VCAP_APPLICATION\" : \'.*instance_index[\": ]*\\([[:digit:]]*\\).*\')" default_tier_name: CloudFoundry diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 28d7dcaab5..098d807777 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -19,11 +19,15 @@ When binding AppDynamics using a user-provided service, it must have name or tag | ---- | ----------- | `account-access-key` | (Optional) The account access key to use when authenticating with the controller | `account-name` | (Optional) The account name to use when authenticating with the controller +| `application-name` | (Optional) the applicationa's name | `host-name` | The controller host name +| `node-name` | (Optional) the application's node name | `port` | (Optional) The controller port | `ssl-enabled` | (Optional) Whether or not to use an SSL connection to the controller | `tier-name` | (Optional) the application's tier name +To provide more complex values such as the `tier-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `tier-name` could be set with a value of `Tier-$(expr "$VCAP_APPLICATION" : '.*instance_index[": ]*\([[:digit:]]*\).*')` to calculate a value from the Cloud Foundry instance index. + ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. @@ -31,7 +35,9 @@ The framework can be configured by modifying the [`config/app_dynamics_agent.yml | Name | Description | ---- | ----------- +| `default_application_name` | This is not provided by default but can be added to specify the application name in the AppDynamics dashboard. This can be overridden with an `application-name` entry in the credentials payload. | `default_tier_name` | The default tier name for this application in the AppDynamics dashboard. This can be overridden with a `tier-name` entry in the credentials payload. +| `default_node_name` | The default node name for this application in the AppDynamics dashboard. The default value is an expression that will be evaluated based on the `instance_index` of the application. This can be overridden with a `node-name` entry in the credentials payload. | `repository_root` | The URL of the AppDynamics repository index ([details][repositories]). | `version` | The version of AppDynamics to use. Candidate versions can be found in [this listing][]. diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index dcb90becef..df9b583ee6 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -34,14 +34,11 @@ def compile def release credentials = @application.services.find_service(FILTER)['credentials'] java_opts = @droplet.java_opts + java_opts.add_javaagent(@droplet.sandbox + 'javaagent.jar') - java_opts - .add_javaagent(@droplet.sandbox + 'javaagent.jar') - .add_system_property('appdynamics.agent.applicationName', "'#{application_name}'") - .add_system_property('appdynamics.agent.tierName', "'#{tier_name(credentials)}'") - .add_system_property('appdynamics.agent.nodeName', - "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')") - + application_name(java_opts, credentials) + tier_name(java_opts, credentials) + node_name(java_opts, credentials) account_access_key(java_opts, credentials) account_name(java_opts, credentials) host_name(java_opts, credentials) @@ -62,12 +59,11 @@ def supports? private_constant :FILTER - def tier_name(credentials) - credentials.key?('tier-name') ? credentials['tier-name'] : @configuration['default_tier_name'] - end - - def application_name - @application.details['application_name'] + def application_name(java_opts, credentials) + name = credentials.key?('application-name') ? credentials['application-name'] : + @configuration['default_application_name'] + name = name ? name : @application.details['application_name'] + java_opts.add_system_property('appdynamics.agent.applicationName', "'#{name}'") end def account_access_key(java_opts, credentials) @@ -86,6 +82,11 @@ def host_name(java_opts, credentials) java_opts.add_system_property 'appdynamics.controller.hostName', host_name end + def node_name(java_opts, credentials) + name = credentials.key?('node-name') ? credentials['node-name'] : @configuration['default_node_name'] + java_opts.add_system_property('appdynamics.agent.nodeName', "#{name}") + end + def port(java_opts, credentials) port = credentials['port'] java_opts.add_system_property 'appdynamics.controller.port', port if port @@ -96,6 +97,11 @@ def ssl_enabled(java_opts, credentials) java_opts.add_system_property 'appdynamics.controller.ssl.enabled', ssl_enabled if ssl_enabled end + def tier_name(java_opts, credentials) + name = credentials.key?('tier-name') ? credentials['tier-name'] : @configuration['default_tier_name'] + java_opts.add_system_property('appdynamics.agent.tierName', "'#{name}'") + end + end end diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 3b5c1540c1..6d4519c696 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -21,7 +21,10 @@ describe JavaBuildpack::Framework::AppDynamicsAgent do include_context 'component_helper' - let(:configuration) { { 'default_tier_name' => 'test-tier-name' } } + let(:configuration) do + { 'default_tier_name' => 'test-tier-name', + 'default_node_name' => "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')" } + end it 'does not detect without app-dynamics-n/a service' do expect(component.detect).to be_nil @@ -77,6 +80,26 @@ end end + context do + let(:credentials) { super().merge 'application-name' => 'another-test-application-name' } + + it 'adds application_name from credentials to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include("-Dappdynamics.agent.applicationName='another-test-application-name'") + end + end + + context do + let(:credentials) { super().merge 'node-name' => 'another-test-node-name' } + + it 'adds node_name from credentials to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dappdynamics.agent.nodeName=another-test-node-name') + end + end + context do let(:credentials) { super().merge 'port' => 'test-port' } From 326844806c4177c9d1df7ec53e7ffdf20d0fdbf7 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 25 Mar 2015 11:23:47 +0000 Subject: [PATCH 018/812] User configuration via variables This commit adds support for overriding buildpack configuration with environment variables. The way Java config is processed has been modified to allow this new support to work when configuring the required version of Java. Includes new tests and documentation, see the main README.md for more details. [#86997400] --- README.md | 9 ++- config/app_dynamics_agent.yml | 1 - config/open_jdk_jre.yml | 6 +- docs/framework-app_dynamics_agent.md | 6 -- .../framework/app_dynamics_agent.rb | 32 ++++------ lib/java_buildpack/jre/open_jdk_like.rb | 18 +++++- .../util/configuration_utils.rb | 41 +++++++++++- .../framework/app_dynamics_agent_spec.rb | 25 +------- spec/java_buildpack/jre/open_jdk_jre_spec.rb | 64 +++++++++++++++---- .../util/configuration_utils_spec.rb | 61 ++++++++++++++++++ 10 files changed, 192 insertions(+), 71 deletions(-) create mode 100644 spec/java_buildpack/util/configuration_utils_spec.rb diff --git a/README.md b/README.md index 71c1f52aee..ae03dd4e24 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,13 @@ The following are _very_ simple examples for deploying the artifact types that w * [Spring Boot CLI](docs/example-spring_boot_cli.md) ## Configuration and Extension -The buildpack supports configuration and extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required configuration and extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. +The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. + +Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. The value of the variable should be valid inline yaml. For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. + +```cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '[version: 1.7.0_+, memory_heuristics: {heap: 85, stack: 10}]'``` + +Environment variable can also be specified in the applications `manifest` file. See the [Environment Variables][] documentation for more information. To learn how to configure various properties of the buildpack, follow the "Configuration" links below. More information on extending the buildpack is available [here](docs/extending.md). @@ -125,6 +131,7 @@ This buildpack is released under version 2.0 of the [Apache License][]. [Cloud Foundry]: http://www.cloudfoundry.com [contributor guidelines]: CONTRIBUTING.md [disables `remote_downloads`]: docs/extending-caches.md#configuration +[Environment Variables]: http://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html#env-block [GitHub's forking functionality]: https://help.github.com/articles/fork-a-repo [Grails]: http://grails.org [Groovy]: http://groovy.codehaus.org diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 31ebf790d9..ecab0ff267 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -17,5 +17,4 @@ --- version: 4.0.+ repository_root: "{default.repository.root}/app-dynamics" -default_node_name: "$(expr \"$VCAP_APPLICATION\" : \'.*instance_index[\": ]*\\([[:digit:]]*\\).*\')" default_tier_name: CloudFoundry diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 6f83d929fe..7358095fac 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -14,16 +14,16 @@ # limitations under the License. # Configuration for JRE repositories keyed by vendor -# To go back to Java 7, permgen should be used instead of metaspace. Please see the documentation for more detail. +# If Java 7 is required, permgen will be used instead of metaspace. Please see the documentation for more detail. --- repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" version: 1.8.0_+ memory_sizes: metaspace: 64m.. - # permgen: 64m.. + permgen: 64m.. memory_heuristics: heap: 75 metaspace: 10 - # permgen: 10 + permgen: 10 stack: 5 native: 10 diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 098d807777..28d7dcaab5 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -19,15 +19,11 @@ When binding AppDynamics using a user-provided service, it must have name or tag | ---- | ----------- | `account-access-key` | (Optional) The account access key to use when authenticating with the controller | `account-name` | (Optional) The account name to use when authenticating with the controller -| `application-name` | (Optional) the applicationa's name | `host-name` | The controller host name -| `node-name` | (Optional) the application's node name | `port` | (Optional) The controller port | `ssl-enabled` | (Optional) Whether or not to use an SSL connection to the controller | `tier-name` | (Optional) the application's tier name -To provide more complex values such as the `tier-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `tier-name` could be set with a value of `Tier-$(expr "$VCAP_APPLICATION" : '.*instance_index[": ]*\([[:digit:]]*\).*')` to calculate a value from the Cloud Foundry instance index. - ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. @@ -35,9 +31,7 @@ The framework can be configured by modifying the [`config/app_dynamics_agent.yml | Name | Description | ---- | ----------- -| `default_application_name` | This is not provided by default but can be added to specify the application name in the AppDynamics dashboard. This can be overridden with an `application-name` entry in the credentials payload. | `default_tier_name` | The default tier name for this application in the AppDynamics dashboard. This can be overridden with a `tier-name` entry in the credentials payload. -| `default_node_name` | The default node name for this application in the AppDynamics dashboard. The default value is an expression that will be evaluated based on the `instance_index` of the application. This can be overridden with a `node-name` entry in the credentials payload. | `repository_root` | The URL of the AppDynamics repository index ([details][repositories]). | `version` | The version of AppDynamics to use. Candidate versions can be found in [this listing][]. diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index df9b583ee6..dcb90becef 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -34,11 +34,14 @@ def compile def release credentials = @application.services.find_service(FILTER)['credentials'] java_opts = @droplet.java_opts - java_opts.add_javaagent(@droplet.sandbox + 'javaagent.jar') - application_name(java_opts, credentials) - tier_name(java_opts, credentials) - node_name(java_opts, credentials) + java_opts + .add_javaagent(@droplet.sandbox + 'javaagent.jar') + .add_system_property('appdynamics.agent.applicationName', "'#{application_name}'") + .add_system_property('appdynamics.agent.tierName', "'#{tier_name(credentials)}'") + .add_system_property('appdynamics.agent.nodeName', + "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')") + account_access_key(java_opts, credentials) account_name(java_opts, credentials) host_name(java_opts, credentials) @@ -59,11 +62,12 @@ def supports? private_constant :FILTER - def application_name(java_opts, credentials) - name = credentials.key?('application-name') ? credentials['application-name'] : - @configuration['default_application_name'] - name = name ? name : @application.details['application_name'] - java_opts.add_system_property('appdynamics.agent.applicationName', "'#{name}'") + def tier_name(credentials) + credentials.key?('tier-name') ? credentials['tier-name'] : @configuration['default_tier_name'] + end + + def application_name + @application.details['application_name'] end def account_access_key(java_opts, credentials) @@ -82,11 +86,6 @@ def host_name(java_opts, credentials) java_opts.add_system_property 'appdynamics.controller.hostName', host_name end - def node_name(java_opts, credentials) - name = credentials.key?('node-name') ? credentials['node-name'] : @configuration['default_node_name'] - java_opts.add_system_property('appdynamics.agent.nodeName', "#{name}") - end - def port(java_opts, credentials) port = credentials['port'] java_opts.add_system_property 'appdynamics.controller.port', port if port @@ -97,11 +96,6 @@ def ssl_enabled(java_opts, credentials) java_opts.add_system_property 'appdynamics.controller.ssl.enabled', ssl_enabled if ssl_enabled end - def tier_name(java_opts, credentials) - name = credentials.key?('tier-name') ? credentials['tier-name'] : @configuration['default_tier_name'] - java_opts.add_system_property('appdynamics.agent.tierName', "'#{name}'") - end - end end diff --git a/lib/java_buildpack/jre/open_jdk_like.rb b/lib/java_buildpack/jre/open_jdk_like.rb index b9862da1fc..ebb624832e 100644 --- a/lib/java_buildpack/jre/open_jdk_like.rb +++ b/lib/java_buildpack/jre/open_jdk_like.rb @@ -18,6 +18,7 @@ require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/jre' require 'java_buildpack/jre/memory/openjdk_memory_heuristic_factory' +require 'java_buildpack/util/tokenized_version' module JavaBuildpack module Jre @@ -65,15 +66,26 @@ def release KEY_MEMORY_SIZES = 'memory_sizes'.freeze - private_constant :KEY_MEMORY_HEURISTICS, :KEY_MEMORY_SIZES + VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0').freeze + + private_constant :KEY_MEMORY_HEURISTICS, :KEY_MEMORY_SIZES, :VERSION_8 def killjava @droplet.sandbox + 'bin/killjava.sh' end def memory - sizes = @configuration[KEY_MEMORY_SIZES] || {} - heuristics = @configuration[KEY_MEMORY_HEURISTICS] || {} + sizes = @configuration[KEY_MEMORY_SIZES] ? @configuration[KEY_MEMORY_SIZES].clone : {} + heuristics = @configuration[KEY_MEMORY_HEURISTICS] ? @configuration[KEY_MEMORY_HEURISTICS].clone : {} + + if @version < VERSION_8 + heuristics.delete 'metaspace' + sizes.delete 'metaspace' + else + heuristics.delete 'permgen' + sizes.delete 'permgen' + end + OpenJDKMemoryHeuristicFactory.create_memory_heuristic(sizes, heuristics, @version).resolve end diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index e3c7cad692..f06fe18649 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -17,12 +17,13 @@ require 'pathname' require 'java_buildpack/util' require 'java_buildpack/logging/logger_factory' +require 'shellwords' require 'yaml' module JavaBuildpack module Util - # Utilities for dealing with Groovy applications + # Utility for loading configuration class ConfigurationUtils private_class_method :new @@ -30,7 +31,8 @@ class ConfigurationUtils class << self # Loads a configuration file from the buildpack configuration directory. If the configuration file does not - # exist, returns an empty hash. + # exist, returns an empty hash. Overlays configuration in a matching environment variable, on top of the loaded + # configuration, if present. Will not add a new configuration key where an existing one does not exist. # # @param [String] identifier the identifier of the configuration # @param [Boolean] should_log whether the contents of the configuration file should be logged. This value @@ -42,6 +44,15 @@ def load(identifier, should_log = true) if file.exist? configuration = YAML.load_file(file) logger.debug { "Configuration from #{file}: #{configuration}" } if should_log + + user_provided = ENV[environment_variable_name(identifier)] + + if user_provided + YAML.load(user_provided).each do |new_prop| + configuration = do_merge(configuration, new_prop, should_log) + end + logger.debug { "Configuration from #{file} modified with: #{user_provided}" } if should_log + end else logger.debug { "No configuration file #{file} found" } if should_log end @@ -53,7 +64,31 @@ def load(identifier, should_log = true) CONFIG_DIRECTORY = Pathname.new(File.expand_path('../../../config', File.dirname(__FILE__))).freeze - private_constant :CONFIG_DIRECTORY + ENVIRONMENT_VARIABLE_PATTERN = 'JBP_CONFIG_' + + private_constant :CONFIG_DIRECTORY, :ENVIRONMENT_VARIABLE_PATTERN + + def do_merge(hash_v1, hash_v2, should_log) + hash_v2.each do |key, value| + if hash_v1.key? key + hash_v1[key] = do_resolve_value(key, hash_v1[key], value, should_log) + else + logger.warn { "User config value for '#{key}' is not valid, existing property not present" } if should_log + end + end + hash_v1 + end + + def do_resolve_value(key, v1, v2, should_log) + return do_merge(v1, v2, should_log) if v1.is_a?(Hash) && v2.is_a?(Hash) + return v2 if (!v1.is_a?(Hash)) && (!v2.is_a?(Hash)) + logger.warn { "User config value for '#{key}' is not valid, must be of a similar type" } if should_log + v1 + end + + def environment_variable_name(config_name) + ENVIRONMENT_VARIABLE_PATTERN + config_name.upcase + end def logger JavaBuildpack::Logging::LoggerFactory.instance.get_logger ConfigurationUtils diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 6d4519c696..3b5c1540c1 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -21,10 +21,7 @@ describe JavaBuildpack::Framework::AppDynamicsAgent do include_context 'component_helper' - let(:configuration) do - { 'default_tier_name' => 'test-tier-name', - 'default_node_name' => "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')" } - end + let(:configuration) { { 'default_tier_name' => 'test-tier-name' } } it 'does not detect without app-dynamics-n/a service' do expect(component.detect).to be_nil @@ -80,26 +77,6 @@ end end - context do - let(:credentials) { super().merge 'application-name' => 'another-test-application-name' } - - it 'adds application_name from credentials to JAVA_OPTS if specified' do - component.release - - expect(java_opts).to include("-Dappdynamics.agent.applicationName='another-test-application-name'") - end - end - - context do - let(:credentials) { super().merge 'node-name' => 'another-test-node-name' } - - it 'adds node_name from credentials to JAVA_OPTS if specified' do - component.release - - expect(java_opts).to include('-Dappdynamics.agent.nodeName=another-test-node-name') - end - end - context do let(:credentials) { super().merge 'port' => 'test-port' } diff --git a/spec/java_buildpack/jre/open_jdk_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_jre_spec.rb index a24922d649..111f1b41ba 100644 --- a/spec/java_buildpack/jre/open_jdk_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_jre_spec.rb @@ -23,16 +23,38 @@ describe JavaBuildpack::Jre::OpenJdkJRE do include_context 'component_helper' + let(:version_8) { VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } + + let(:version_7) { VERSION_7 = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } + + let(:configuration) do + { 'memory_sizes' => { 'metaspace' => '64m..', + 'permgen' => '64m..' }, + 'memory_heuristics' => { 'heap' => '75', + 'metaspace' => '10', + 'permgen' => '10', + 'stack' => '5', + 'native' => '10' } } + end + let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } - let(:memory_heuristic) { double('MemoryHeuristic', resolve: %w(opt-1 opt-2)) } + let(:memory_heuristic_7) { double('MemoryHeuristic', resolve: %w(opt-7-1 opt-7-2)) } + + let(:memory_heuristic_8) { double('MemoryHeuristic', resolve: %w(opt-8-1 opt-8-2)) } before do - allow(JavaBuildpack::Jre::WeightBalancingMemoryHeuristic).to receive(:new).and_return(memory_heuristic) + allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item).and_return([version_8, 'test-uri']) + allow(JavaBuildpack::Jre::WeightBalancingMemoryHeuristic).to receive(:new).with({ 'permgen' => '64m..' }, + anything, anything, anything) + .and_return(memory_heuristic_7) + allow(JavaBuildpack::Jre::WeightBalancingMemoryHeuristic).to receive(:new).with({ 'metaspace' => '64m..' }, + anything, anything, anything) + .and_return(memory_heuristic_8) end it 'detects with id of openjdk_jre-' do - expect(component.detect).to eq("open-jdk-jre=#{version}") + expect(component.detect).to eq("open-jdk-jre=#{version_8}") end it 'extracts Java from a GZipped TAR', @@ -50,14 +72,6 @@ expect(java_home.root).to eq(sandbox) end - it 'adds memory options to java_opts' do - component.detect - component.release - - expect(java_opts).to include('opt-1') - expect(java_opts).to include('opt-2') - end - it 'adds OnOutOfMemoryError to java_opts' do component.detect component.release @@ -81,4 +95,32 @@ expect(java_opts).to include('-Djava.io.tmpdir=$TMPDIR') end + it 'removes memory options for a java 8 app', + cache_fixture: 'stub-java.tar.gz' do + + component.detect + component.release + + expect(java_opts).to include('opt-8-1') + expect(java_opts).to include('opt-8-2') + end + + context do + + before do + allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item).and_return([version_7, 'test-uri']) + end + + it 'removes memory options for a java 7 app', + cache_fixture: 'stub-java.tar.gz' do + + component.detect + component.release + + expect(java_opts).to include('opt-7-1') + expect(java_opts).to include('opt-7-2') + end + + end + end diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb new file mode 100644 index 0000000000..2557d1e0b3 --- /dev/null +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -0,0 +1,61 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/util' +require 'java_buildpack/util/configuration_utils' +require 'logging_helper' +require 'pathname' +require 'spec_helper' +require 'yaml' + +describe JavaBuildpack::Util::ConfigurationUtils do + include_context 'logging_helper' + + it 'not load absent configuration file' do + allow_any_instance_of(Pathname).to receive(:exist?).and_return(false) + expect(described_class.load('test')).to eq({}) + end + + context do + + before do + allow_any_instance_of(Pathname).to receive(:exist?).and_return(true) + allow(YAML).to receive(:load_file).and_return('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }) + end + + it 'load configuration file' do + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }) + end + + context do + + let(:environment) do + { 'JBP_CONFIG_TEST' => '[bar: {alpha: {one: 3, two: {one: 3}}, bravo: newValue}, foo: lion]' } + end + + it 'overlays matching environment variables' do + + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 3, 'two' => 'dog' } }) + end + + end + + end + +end From c0a6a1f2f8ec58e92b0aeb5a6a4bd02cde37aaa4 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 19 Mar 2015 15:53:49 +0000 Subject: [PATCH 019/812] Configurable AppDynamics application & node names This commit makes it possible to supply values for the AppDynamics application and node names in the configuration and through service credentials. Testing and documentation also updated. [#89413382] --- config/app_dynamics_agent.yml | 1 + docs/framework-app_dynamics_agent.md | 6 ++++ .../framework/app_dynamics_agent.rb | 32 +++++++++++-------- .../framework/app_dynamics_agent_spec.rb | 25 ++++++++++++++- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index ecab0ff267..31ebf790d9 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -17,4 +17,5 @@ --- version: 4.0.+ repository_root: "{default.repository.root}/app-dynamics" +default_node_name: "$(expr \"$VCAP_APPLICATION\" : \'.*instance_index[\": ]*\\([[:digit:]]*\\).*\')" default_tier_name: CloudFoundry diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 28d7dcaab5..098d807777 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -19,11 +19,15 @@ When binding AppDynamics using a user-provided service, it must have name or tag | ---- | ----------- | `account-access-key` | (Optional) The account access key to use when authenticating with the controller | `account-name` | (Optional) The account name to use when authenticating with the controller +| `application-name` | (Optional) the applicationa's name | `host-name` | The controller host name +| `node-name` | (Optional) the application's node name | `port` | (Optional) The controller port | `ssl-enabled` | (Optional) Whether or not to use an SSL connection to the controller | `tier-name` | (Optional) the application's tier name +To provide more complex values such as the `tier-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `tier-name` could be set with a value of `Tier-$(expr "$VCAP_APPLICATION" : '.*instance_index[": ]*\([[:digit:]]*\).*')` to calculate a value from the Cloud Foundry instance index. + ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. @@ -31,7 +35,9 @@ The framework can be configured by modifying the [`config/app_dynamics_agent.yml | Name | Description | ---- | ----------- +| `default_application_name` | This is not provided by default but can be added to specify the application name in the AppDynamics dashboard. This can be overridden with an `application-name` entry in the credentials payload. | `default_tier_name` | The default tier name for this application in the AppDynamics dashboard. This can be overridden with a `tier-name` entry in the credentials payload. +| `default_node_name` | The default node name for this application in the AppDynamics dashboard. The default value is an expression that will be evaluated based on the `instance_index` of the application. This can be overridden with a `node-name` entry in the credentials payload. | `repository_root` | The URL of the AppDynamics repository index ([details][repositories]). | `version` | The version of AppDynamics to use. Candidate versions can be found in [this listing][]. diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index dcb90becef..df9b583ee6 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -34,14 +34,11 @@ def compile def release credentials = @application.services.find_service(FILTER)['credentials'] java_opts = @droplet.java_opts + java_opts.add_javaagent(@droplet.sandbox + 'javaagent.jar') - java_opts - .add_javaagent(@droplet.sandbox + 'javaagent.jar') - .add_system_property('appdynamics.agent.applicationName', "'#{application_name}'") - .add_system_property('appdynamics.agent.tierName', "'#{tier_name(credentials)}'") - .add_system_property('appdynamics.agent.nodeName', - "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')") - + application_name(java_opts, credentials) + tier_name(java_opts, credentials) + node_name(java_opts, credentials) account_access_key(java_opts, credentials) account_name(java_opts, credentials) host_name(java_opts, credentials) @@ -62,12 +59,11 @@ def supports? private_constant :FILTER - def tier_name(credentials) - credentials.key?('tier-name') ? credentials['tier-name'] : @configuration['default_tier_name'] - end - - def application_name - @application.details['application_name'] + def application_name(java_opts, credentials) + name = credentials.key?('application-name') ? credentials['application-name'] : + @configuration['default_application_name'] + name = name ? name : @application.details['application_name'] + java_opts.add_system_property('appdynamics.agent.applicationName', "'#{name}'") end def account_access_key(java_opts, credentials) @@ -86,6 +82,11 @@ def host_name(java_opts, credentials) java_opts.add_system_property 'appdynamics.controller.hostName', host_name end + def node_name(java_opts, credentials) + name = credentials.key?('node-name') ? credentials['node-name'] : @configuration['default_node_name'] + java_opts.add_system_property('appdynamics.agent.nodeName', "#{name}") + end + def port(java_opts, credentials) port = credentials['port'] java_opts.add_system_property 'appdynamics.controller.port', port if port @@ -96,6 +97,11 @@ def ssl_enabled(java_opts, credentials) java_opts.add_system_property 'appdynamics.controller.ssl.enabled', ssl_enabled if ssl_enabled end + def tier_name(java_opts, credentials) + name = credentials.key?('tier-name') ? credentials['tier-name'] : @configuration['default_tier_name'] + java_opts.add_system_property('appdynamics.agent.tierName', "'#{name}'") + end + end end diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 3b5c1540c1..6d4519c696 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -21,7 +21,10 @@ describe JavaBuildpack::Framework::AppDynamicsAgent do include_context 'component_helper' - let(:configuration) { { 'default_tier_name' => 'test-tier-name' } } + let(:configuration) do + { 'default_tier_name' => 'test-tier-name', + 'default_node_name' => "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')" } + end it 'does not detect without app-dynamics-n/a service' do expect(component.detect).to be_nil @@ -77,6 +80,26 @@ end end + context do + let(:credentials) { super().merge 'application-name' => 'another-test-application-name' } + + it 'adds application_name from credentials to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include("-Dappdynamics.agent.applicationName='another-test-application-name'") + end + end + + context do + let(:credentials) { super().merge 'node-name' => 'another-test-node-name' } + + it 'adds node_name from credentials to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dappdynamics.agent.nodeName=another-test-node-name') + end + end + context do let(:credentials) { super().merge 'port' => 'test-port' } From 72f4580b7b765ba70b4ccda49a8ad4011b168fc6 Mon Sep 17 00:00:00 2001 From: Robbie Clutton Date: Sun, 22 Mar 2015 07:22:03 +0000 Subject: [PATCH 020/812] Embedded web server example. The other buildpack examples don't make clear how to make use of the environment variables in order to include a web server / servlet container within the application. This example does that through showing how using Jetty as an embedded container works using Cloud Foundry. --- README.md | 1 + docs/example-embedded-web-server.md | 30 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 docs/example-embedded-web-server.md diff --git a/README.md b/README.md index 71c1f52aee..316b67b906 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ cf push -p -b https://github.com/cloudfoundry/java-buildpa ## Examples The following are _very_ simple examples for deploying the artifact types that we support. +* [Embedded web server](docs/example-embedded-web-server.md) * [Grails](docs/example-grails.md) * [Groovy](docs/example-groovy.md) * [Java Main](docs/example-java_main.md) diff --git a/docs/example-embedded-web-server.md b/docs/example-embedded-web-server.md new file mode 100644 index 0000000000..52d7291a9d --- /dev/null +++ b/docs/example-embedded-web-server.md @@ -0,0 +1,30 @@ +# Embedded web server examples + +The Java Buildpack can run applications which provide their own web server or servlet container, provided as JAR files. + +## Example + +This example uses Jetty as an embedded web server, but should be applicable for other technologies. + +```java + +public static void main(String[] args) { + int port = Integer.parseInt(System.getenv("PORT")); + Server server = new Server(port); + server.setHandler(new AbstractHandler() { + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + response.setContentType("text/html;charset=utf-8"); + response.setStatus(HttpServletResponse.SC_OK); + baseRequest.setHandled(true); + response.getWriter().println("

Hello, world

"); + } + }); + server.start(); + server.join(); +} +``` + +The important takeaway is to note that the port comes from the environment variable `port`. Other variables are detailed in the [Cloud Foundry developer guide](http://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html). When the application is built as an executable JAR file, it will be treated as a [Java Main](https://github.com/cloudfoundry/java-buildpack/blob/master/docs/example-java_main.md) application. + + From b18b155b8f0fc2f2ead512113aacbabb69c8785d Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 26 Mar 2015 14:29:04 +0000 Subject: [PATCH 021/812] Tomcat connectionTimeout to 20s This commit changes the default Tomcat connection timeout to 20000ms. When this value is not specified the default is 60000ms which is too high. The value of 20000ms has been chosen to alight with Tomcats configured out of the box default. See: https://github.com/cloudfoundry/java-buildpack/pull/158 [#91083074] --- resources/tomcat/conf/server.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/tomcat/conf/server.xml b/resources/tomcat/conf/server.xml index ec97191ec5..bdfd3bb7d7 100644 --- a/resources/tomcat/conf/server.xml +++ b/resources/tomcat/conf/server.xml @@ -19,7 +19,7 @@ - + From c21900ac481d37236a16aa9f91b4aa99182b850b Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Fri, 27 Mar 2015 15:25:21 +0000 Subject: [PATCH 022/812] Document the use of urandom This commit adds documentation about the use and configuration of '/dev/urandom' as an alternative source of entropy. See: https://groups.google.com/a/cloudfoundry.org/forum/#!msg/vcap-dev/GogAsIvBeVo/LqFPEDOcXysJ See: https://groups.google.com/a/cloudfoundry.org/forum/#!msg/vcap-dev/liTZDW9hgm4/d3GeC5AL_OAJ [#80431356] --- docs/container-tomcat.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index d0cd1c0679..0f587d0a44 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -60,6 +60,16 @@ To enable Redis-based session replication, simply bind a Redis service containin ### GemFire To enable GemFire-based session replication, simply bind a [GemFire service][] containing a name, label, or tag that has `session_replication` as a substring. GemFire services intended to be used for session replication will automatically have a tag of 'session_replication'. +## Managing Entropy +Entropy from `/dev/random` is used heavily to create session ids, and on startup for initializing SecureRandom, which can then cause instances to fail to start in time (See the [Tomcat Wiki]). Also, the entropy is shared so it's possible for a single app to starve the DEA of entropy and cause apps in other containers that make use of entropy to be blocked. +If this is an issue then configuring `/dev/urandom` as an alternative source of entropy should help. It is unlikely, but possible, that this may cause some security issues which should be taken in to account. + +Example in a manifest.yml +``` +env: + JAVA_OPTS: -Djava.security.egd=file:///dev/urandom +``` + ## Supporting Functionality Additional supporting functionality can be found in the [`java-buildpack-support`][] Git repository. @@ -70,4 +80,5 @@ Additional supporting functionality can be found in the [`java-buildpack-support [repositories]: extending-repositories.md [Spring profiles]:http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/ [`SPRING_PROFILES_ACTIVE`]: http://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/org/springframework/core/env/AbstractEnvironment.html#ACTIVE_PROFILES_PROPERTY_NAME +[Tomcat Wiki]: http://wiki.apache.org/tomcat/HowTo/FasterStartUp [version syntax]: extending-repositories.md#version-syntax-and-ordering From e78fa0ed9300894d747cc49c3f5086d01bd26ef9 Mon Sep 17 00:00:00 2001 From: savitaashture Date: Fri, 27 Mar 2015 17:29:59 -0400 Subject: [PATCH 023/812] Updated the document --- docs/extending-application.md | 7 +++++-- docs/extending-base_component.md | 6 +++++- docs/extending-caches.md | 15 ++++++++------- docs/extending-droplet.md | 9 ++++++--- docs/extending-modular_component.md | 7 ++++--- docs/extending-repositories.md | 8 +++++--- 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/docs/extending-application.md b/docs/extending-application.md index a8c0bb6a1d..af904e05f5 100644 --- a/docs/extending-application.md +++ b/docs/extending-application.md @@ -38,8 +38,11 @@ A helper type (`JavaBuildpack::Component::Services`) that enables querying of th # +filter+ matches exactly one service, +false+ otherwise. # # @param [Regexp, String] filter a +RegExp+ or +String+ to match against the name, label, and tags of the services -# @return [Boolean] +true+ if the +filter+ matches exactly one service, +false+ otherwise. -def one_service?(filter) +# @param [String] required_credentials an optional list of keys or groups of keys, where at least one key from the +# group, must exist in the credentials payload of the candidate service +# @return [Boolean] +true+ if the +filter+ matches exactly one service with the required credentials, +false+ +# otherwise. +def one_service?(filter, *required_credentials) # Compares the name, label, and tags of each service to the given +filter+. The method returns the first service # that the +filter+ matches. If no service matches, returns +nil+ diff --git a/docs/extending-base_component.md b/docs/extending-base_component.md index 1643fadf85..836812a2a8 100644 --- a/docs/extending-base_component.md +++ b/docs/extending-base_component.md @@ -48,7 +48,7 @@ def release # @param [String] uri # @param [String] name an optional name for the download. Defaults to +@component_name+. # @return [Void] -def download(version, uri, name = @component_name, &block) +def download(version, uri, name = @component_name) # Downloads a given JAR file and stores it. # @@ -57,6 +57,7 @@ def download(version, uri, name = @component_name, &block) # @param [String] jar_name the name to save the jar as # @param [Pathname] target_directory the directory to store the JAR file in. Defaults to the component's sandbox. # @param [String] name an optional name for the download. Defaults to +@component_name+. +# @return [Void] def download_jar(version, uri, jar_name, target_directory = @droplet.sandbox, name = @component_name) # Downloads a given TAR file and expands it. @@ -65,6 +66,7 @@ def download_jar(version, uri, jar_name, target_directory = @droplet.sandbox, na # @param [String] uri the uri of the download # @param [Pathname] target_directory the directory to expand the TAR file to. Defaults to the component's sandbox. # @param [String] name an optional name for the download and expansion. Defaults to +@component_name+. +# @return [Void] def download_tar(version, uri, target_directory = @droplet.sandbox, name = @component_name) # Downloads a given ZIP file and expands it. @@ -72,11 +74,13 @@ def download_tar(version, uri, target_directory = @droplet.sandbox, name = @comp # @param [Boolean] strip_top_level whether to strip the top-level directory when expanding. Defaults to +true+. # @param [Pathname] target_directory the directory to expand the ZIP file to. Defaults to the component's sandbox. # @param [String] name an optional name for the download. Defaults to +@component_name+. +# @return [Void] def download_zip(version, uri, strip_top_level = true, target_directory = @droplet.sandbox, name = @component_name) # Wrap the execution of a block with timing information # # @param [String] caption the caption to print when timing starts +# @return [Void] def with_timing(caption) ``` diff --git a/docs/extending-caches.md b/docs/extending-caches.md index 512d8680f1..b4faae9e0e 100644 --- a/docs/extending-caches.md +++ b/docs/extending-caches.md @@ -51,20 +51,21 @@ Caching can be configured by modifying the [`config/cache.yml`][] file in the bu The [`DownloadCache`][] is the most generic of the two caches. It allows you to create a cache that persists files any that write access is available. The constructor signature looks the following: ```ruby -# Creates an instance of the cache that is backed by the filesystem rooted at +cache_root+ +# Creates an instance of the cache that is backed by a number of filesystem locations. The first argument +# (+mutable_cache_root+) is the only location that downloaded files will be stored in. # -# @param [String] cache_root the filesystem root for downloaded files to be cached in -def initialize(cache_root = Dir.tmpdir) +# @param [Pathname] mutable_cache_root the filesystem location in which find cached files in. This will also be +# the location that all downloaded files are written to. +# @param [Pathname] immutable_cache_roots other filesystem locations to find cached files in. No files will be +# written to these locations. +def initialize(mutable_cache_root = Pathname.new(Dir.tmpdir), *immutable_cache_roots) ``` ## `JavaBuildpack::Util::Cache::ApplicationCache` The [`ApplicationCache`][] is a cache that persists files into the application cache passed to the `compile` script. It examines `ARGV[1]` for the cache location and configures itself accordingly. ```ruby -# Creates an instance that is configured to use the application cache. The application cache location is defined by -# the second argument (ARGV[1]) to the +compile+ script. -# -# @raise if the second argument (ARGV[1]) to the +compile+ script is +nil+ +# Creates an instance of the cache that is backed by the the application cache def initialize ``` diff --git a/docs/extending-droplet.md b/docs/extending-droplet.md index 798bfa0dbe..51988ddf2e 100644 --- a/docs/extending-droplet.md +++ b/docs/extending-droplet.md @@ -32,7 +32,8 @@ attr_reader :sandbox # Copy resources from a components resources directory to a directory # -# @param [Pathname] target_directory the directory to copy to. Default to a component's +sandbox+ +# @param [Pathname] target_directory the directory to copy to. Defaults to the component's +sandbox+. +# @return [Void] def copy_resources(target_directory = @sandbox) ``` @@ -48,6 +49,7 @@ def as_classpath # Symlink the contents of the collection to a destination directory. # # @param [Pathname] destination the destination to link to +# @return [Void] def link_to(destination) ``` @@ -58,7 +60,7 @@ The id of the component, as determined by the buildpack. This is used in variou One of two helper types (`JavaBuildpack::Component::ImmutableJavaHome`, `JavaBuildpack::Component::MutableJavaHome`) that enables the mutation and retrieval of the droplet's `JAVA_HOME`. Components that are JREs will be given the `MutableJavaHome` in order to set the value. All other components will be given the `ImmutableJavaHome` in order to retrieve the value. ```ruby -# Returns the path of +JAVA_HOME+ as an environment variable formatted as +JAVA_HOME="$PWD/"+ +# Returns the path of +JAVA_HOME+ as an environment variable formatted as +JAVA_HOME=$PWD/+ # # @return [String] the path of +JAVA_HOME+ as an environment variable def as_env_var @@ -66,9 +68,10 @@ def as_env_var # Execute a block with the +JAVA_HOME+ environment variable set # # @yield yields to block with the +JAVA_HOME+ environment variable set +# @return [Object] the returned value of the block def do_with -# @return [String] the root of the droplet's +JAVA_HOME+ +# @return [String] the root of the droplet's +JAVA_HOME+ formatted as +$PWD/+ def root # Sets the root of the droplet's +JAVA_HOME+ diff --git a/docs/extending-modular_component.md b/docs/extending-modular_component.md index 8760e930a9..e61e7649e7 100644 --- a/docs/extending-modular_component.md +++ b/docs/extending-modular_component.md @@ -10,11 +10,12 @@ This base class is recommended for use by any component that is sufficiently com # components are expected to return the command required to run the application. def command -# The modules that make up this component +# The sub_components that make up this component # # @param [Hash] context the context of the component -# @return [Array] a collection of +BaseComponent+s that make up the modules of this component -def modules(context) +# @return [Array] a collection of +BaseComponent+s that make up the sub_components of this +# component +def sub_components(_context) # Whether or not this component supports this application # diff --git a/docs/extending-repositories.md b/docs/extending-repositories.md index 84604ef680..82e5ea9434 100644 --- a/docs/extending-repositories.md +++ b/docs/extending-repositories.md @@ -22,15 +22,17 @@ An example filesystem might look like: The main class used when dealing with a repository is [`JavaBuildpack::Repository::ConfiguredItem`][]. It provides a single method that is used to resolve a specific version and its URI. ```ruby -# Finds an instance of the file based on the configuration. +# Finds an instance of the file based on the configuration and wraps any exceptions +# to identify the component. # +# @param [String] component_name the name of the component # @param [Hash] configuration the configuration # @option configuration [String] :repository_root the root directory of the repository # @option configuration [String] :version the version of the file to resolve # @param [Block, nil] version_validator an optional version validation block -# @return [JavaBuildpack::Util::TokenizedVersion] the chosen version of the file # @return [String] the URI of the chosen version of the file -def find_item(configuration, &version_validator) +# @return [JavaBuildpack::Util::TokenizedVersion] the chosen version of the file +def find_item(component_name, configuration) ``` Usage of the class might look like the following: From 7be64de1af9b30bdf00ca6bf6fc750453c265860 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 1 Apr 2015 15:08:59 +0100 Subject: [PATCH 024/812] Update docs for setting env variables The documentation contained no information about how to escape strings when setting an environment variable on an application to update the buildpack configuration. This change adds an example. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 75e47c61c2..86a8fcb75a 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,10 @@ Buildpack configuration can be overridden with an environment variable matching ```cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '[version: 1.7.0_+, memory_heuristics: {heap: 85, stack: 10}]'``` +If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. + +```cf set-env my-application JBP_CONFIG_REPOSITORY '[ default_repository_root: "http://repo.example.io" ]'``` + Environment variable can also be specified in the applications `manifest` file. See the [Environment Variables][] documentation for more information. To learn how to configure various properties of the buildpack, follow the "Configuration" links below. More information on extending the buildpack is available [here](docs/extending.md). From 897989c2532fe744af745d3c0d41062c5ef14fb7 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 7 Apr 2015 13:38:22 +0100 Subject: [PATCH 025/812] Document the use of urandom This commit updates documentation about the use and configuration of '/dev/urandom' after feedback recieved on GitHub. [#80431356] --- docs/container-tomcat.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index 0f587d0a44..8f5f49b608 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -61,8 +61,8 @@ To enable Redis-based session replication, simply bind a Redis service containin To enable GemFire-based session replication, simply bind a [GemFire service][] containing a name, label, or tag that has `session_replication` as a substring. GemFire services intended to be used for session replication will automatically have a tag of 'session_replication'. ## Managing Entropy -Entropy from `/dev/random` is used heavily to create session ids, and on startup for initializing SecureRandom, which can then cause instances to fail to start in time (See the [Tomcat Wiki]). Also, the entropy is shared so it's possible for a single app to starve the DEA of entropy and cause apps in other containers that make use of entropy to be blocked. -If this is an issue then configuring `/dev/urandom` as an alternative source of entropy should help. It is unlikely, but possible, that this may cause some security issues which should be taken in to account. +Entropy from `/dev/random` is used heavily to create session ids, and on startup for initializing `SecureRandom`, which can then cause instances to fail to start in time (see the [Tomcat wiki]). Also, the entropy is shared so it's possible for a single app to starve the DEA of entropy and cause apps in other containers that make use of entropy to be blocked. +If this is an issue then configuring `/dev/urandom` as an alternative source of entropy may help. It is unlikely, but possible, that this may cause some security issues which should be taken in to account. Example in a manifest.yml ``` @@ -80,5 +80,5 @@ Additional supporting functionality can be found in the [`java-buildpack-support [repositories]: extending-repositories.md [Spring profiles]:http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/ [`SPRING_PROFILES_ACTIVE`]: http://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/org/springframework/core/env/AbstractEnvironment.html#ACTIVE_PROFILES_PROPERTY_NAME -[Tomcat Wiki]: http://wiki.apache.org/tomcat/HowTo/FasterStartUp +[Tomcat wiki]: http://wiki.apache.org/tomcat/HowTo/FasterStartUp [version syntax]: extending-repositories.md#version-syntax-and-ordering From 254245aac197ceedfc53a3fb38bfcf5ea68ddc75 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 9 Apr 2015 14:06:29 +0100 Subject: [PATCH 026/812] Honor an applications env variables Removing unused code and making the shell command more flexible. The unused in this repo code is required in the downstream tc-Server repo where it is doing the wrong thing. [#90500196] --- .../component/immutable_java_home.rb | 14 -------------- lib/java_buildpack/util/shell.rb | 8 ++++---- .../component/immutable_java_home_spec.rb | 6 ------ 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index 830e423582..9a19f54da6 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -42,20 +42,6 @@ def as_env_var "JAVA_HOME=#{root}" end - # Execute a block with the +JAVA_HOME+ environment variable set - # - # @yield yields to block with the +JAVA_HOME+ environment variable set - # @return [Object] the returned value of the block - def do_with - previous_value = ENV['JAVA_HOME'] - begin - ENV['JAVA_HOME'] = @delegate.root.cleanpath.to_s - yield - ensure - ENV['JAVA_HOME'] = previous_value - end - end - # @return [String] the root of the droplet's +JAVA_HOME+ formatted as +$PWD/+ def root qualify_path @delegate.root diff --git a/lib/java_buildpack/util/shell.rb b/lib/java_buildpack/util/shell.rb index 924de030d4..83222d96f2 100644 --- a/lib/java_buildpack/util/shell.rb +++ b/lib/java_buildpack/util/shell.rb @@ -25,12 +25,12 @@ module Shell # A +system()+-like command that ensure that the execution fails if the command returns a non-zero exit code # - # @param [String] command the command to run + # @param [Object] args The command to run # @return [Void] - def shell(command) - Open3.popen3(command) do |_stdin, stdout, stderr, wait_thr| + def shell(*args) + Open3.popen3(*args) do |_stdin, stdout, stderr, wait_thr| if wait_thr.value != 0 - puts "\nCommand '#{command}' has failed" + puts "\nCommand '#{args.join ' '}' has failed" puts "STDOUT: #{stdout.gets}" puts "STDERR: #{stderr.gets}" diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index a1cdd7e2e9..fde998b336 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -27,12 +27,6 @@ expect(immutable_java_home.as_env_var).to eq('JAVA_HOME=$PWD/test-java-home') end - it 'sets JAVA_HOME environment variable' do - immutable_java_home.do_with do - expect(ENV['JAVA_HOME']).to eq('test-java-home') - end - end - it 'returns the qualified delegate root' do expect(immutable_java_home.root).to eq('$PWD/test-java-home') end From 397865f25e65203bab9bd8ad605071b141c8986f Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 9 Apr 2015 17:48:40 +0100 Subject: [PATCH 027/812] Fix long time bug in shell commands Running a Shell command with the built in shell utility only returns a single line of the result on either STDOUT or STDERR. This commit fixes this to return all output from the running of a command or commands. --- lib/java_buildpack/util/shell.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/util/shell.rb b/lib/java_buildpack/util/shell.rb index 83222d96f2..ed4a654774 100644 --- a/lib/java_buildpack/util/shell.rb +++ b/lib/java_buildpack/util/shell.rb @@ -31,8 +31,8 @@ def shell(*args) Open3.popen3(*args) do |_stdin, stdout, stderr, wait_thr| if wait_thr.value != 0 puts "\nCommand '#{args.join ' '}' has failed" - puts "STDOUT: #{stdout.gets}" - puts "STDERR: #{stderr.gets}" + puts "STDOUT: #{stdout.gets nil}" + puts "STDERR: #{stderr.gets nil}" fail end From a2269a97a716488281f4afee5ff2b14489793e5f Mon Sep 17 00:00:00 2001 From: Dmitri Gabbasov Date: Mon, 13 Apr 2015 15:18:55 +0300 Subject: [PATCH 028/812] Improve the JRebel framework * Drop the requirement for having rebel.xml inside the application, having rebel-remote.xml is enough. * Detect rebel-remote.xml inside embedded JAR files. * Download JRebel from the ZeroTurnaround repository. * Use the new JRebel core (with the native agent), as opposed to the legacy one. * Enable JRebel logging. --- config/jrebel_agent.yml | 2 +- docs/framework-jrebel_agent.md | 13 ++++-- lib/java_buildpack/component/java_opts.rb | 10 +++++ lib/java_buildpack/framework/jrebel_agent.rb | 31 ++++++++++----- .../rebel-remote.xml | 0 .../WEB-INF/classes/rebel-remote.xml} | 0 .../WEB-INF/lib/dependency.jar | Bin 0 -> 166 bytes spec/fixtures/stub-jrebel-archive.zip | Bin 480 -> 1262 bytes .../framework/jrebel_agent_spec.rb | 37 ++++++++++++------ 9 files changed, 67 insertions(+), 26 deletions(-) rename spec/fixtures/{framework_jrebel_app => framework_jrebel_app_simple}/rebel-remote.xml (100%) rename spec/fixtures/{framework_jrebel_app/rebel.xml => framework_jrebel_app_war/WEB-INF/classes/rebel-remote.xml} (100%) create mode 100644 spec/fixtures/framework_jrebel_app_war_with_jar/WEB-INF/lib/dependency.jar diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml index 31aa9e5369..89d7e8bcfe 100644 --- a/config/jrebel_agent.yml +++ b/config/jrebel_agent.yml @@ -16,4 +16,4 @@ # Configuration for the JRebel framework --- version: 6.+ -repository_root: "{default.repository.root}/jrebel" +repository_root: "http://dl.zeroturnaround.com/jrebel" diff --git a/docs/framework-jrebel_agent.md b/docs/framework-jrebel_agent.md index 9a44e9d090..38f95550ab 100644 --- a/docs/framework-jrebel_agent.md +++ b/docs/framework-jrebel_agent.md @@ -1,10 +1,11 @@ # JRebel Agent Framework -The JRebel Agent Framework causes an application to be automatically configured to work with an IDE using [JRebel][]. + +The JRebel Agent Framework causes an application to be automatically configured to work with [JRebel][]. Pushing any [JRebel Cloud/Remote][] enabled application (containing `rebel-remote.xml`) will automatically download the latest version of [JRebel][] and set it up for use. - + @@ -13,6 +14,8 @@ The JRebel Agent Framework causes an application to be automatically configured
Detection CriterionExistence of the `rebel.xml` and `rebel-remote.xml` files in either the root or `WEB-INF/classes` directory or the application.Existence of a rebel-remote.xml file inside the application archive. This file is present in every application that is configured to use JRebel Cloud/Remote.
Tags
Tags are printed to standard output by the buildpack detect script +For more information regarding setup and configuration, please refer to the [JRebel with Pivotal Cloud Foundry tutorial][pivotal]. + ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. @@ -21,11 +24,13 @@ The framework can be configured by modifying the [`config/jrebel_agent.yml`][] f | Name | Description | ---- | ----------- | `repository_root` | The URL of the JRebel repository index ([details][repositories]). -| `version` | The version of Jrebel to use. Candidate versions can be found in [this listing][]. +| `version` | The version of JRebel to use. Candidate versions can be found in [this listing][]. [Configuration and Extension]: ../README.md#configuration-and-extension [`config/jrebel_agent.yml`]: ../config/jrebel_agent.yml +[JRebel Cloud/Remote]: http://manuals.zeroturnaround.com/jrebel/remoting/index.html [JRebel]: http://zeroturnaround.com/software/jrebel/ +[pivotal]: http://manuals.zeroturnaround.com/jrebel/remoting/pivotal.html [repositories]: extending-repositories.md -[this listing]: http://download.pivotal.io.s3.amazonaws.com/jrebel/index.yml +[this listing]: http://dl.zeroturnaround.com/jrebel/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index cca1517fee..18d552082a 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -43,6 +43,16 @@ def add_javaagent(path) self end + # Adds an +agentpath+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to + # ensure that the path is always accurate. + # + # @param [Pathname] path the path to the +native+ +agent+ + # @return [JavaOpts] +self+ for chaining + def add_agentpath(path) + self << "-agentpath:#{qualify_path path}" + self + end + # Adds a +bootclasspath/p+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to # ensure that the path is always accurate. # diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index 36eb543162..13f0fc4d98 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -24,36 +24,49 @@ module Framework # Encapsulates the functionality for enabling zero-touch JRebel support. class JrebelAgent < JavaBuildpack::Component::VersionedDependencyComponent + def initialize(context, &version_validator) + super(context, &version_validator) + @component_name = 'JRebel Agent' + end + # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_zip false - FileUtils.mv(download_location + 'jrebel.jar', @droplet.sandbox + jar_name) - FileUtils.remove_dir(download_location, true) + download_zip end # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts - .add_javaagent(@droplet.sandbox + jar_name) - .add_bootclasspath_p(@droplet.sandbox + jar_name) + .add_agentpath(@droplet.sandbox + ('lib/' + lib_name)) .add_system_property('rebel.remoting_plugin', true) + .add_system_property('rebel.log', true) + .add_system_property('rebel.cloud.platform', 'cloudfoundry/java-buildpack') end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - jrebel_configured?(@application.root) || jrebel_configured?(@application.root + 'WEB-INF/classes') + jrebel_configured?(@application.root) || jrebel_configured?(@application.root + 'WEB-INF/classes') || + jars_with_jrebel_configured?(@application.root) end private def jrebel_configured?(root_path) - (root_path + 'rebel.xml').exist? && (root_path + 'rebel-remote.xml').exist? + (root_path + 'rebel-remote.xml').exist? + end + + def jars_with_jrebel_configured?(root_path) + (root_path + '**/*.jar').glob.any? { |jar| ! `unzip -l "#{jar}" | grep "rebel-remote\\.xml$"`.strip.empty? } + end + + def lib_name + architecture == 'x86_64' || architecture == 'i686' ? 'libjrebel64.so' : 'libjrebel32.so' end - def download_location - @droplet.sandbox + 'jrebel' + def architecture + `uname -m`.strip end end diff --git a/spec/fixtures/framework_jrebel_app/rebel-remote.xml b/spec/fixtures/framework_jrebel_app_simple/rebel-remote.xml similarity index 100% rename from spec/fixtures/framework_jrebel_app/rebel-remote.xml rename to spec/fixtures/framework_jrebel_app_simple/rebel-remote.xml diff --git a/spec/fixtures/framework_jrebel_app/rebel.xml b/spec/fixtures/framework_jrebel_app_war/WEB-INF/classes/rebel-remote.xml similarity index 100% rename from spec/fixtures/framework_jrebel_app/rebel.xml rename to spec/fixtures/framework_jrebel_app_war/WEB-INF/classes/rebel-remote.xml diff --git a/spec/fixtures/framework_jrebel_app_war_with_jar/WEB-INF/lib/dependency.jar b/spec/fixtures/framework_jrebel_app_war_with_jar/WEB-INF/lib/dependency.jar new file mode 100644 index 0000000000000000000000000000000000000000..89c8886b1106b8819e3db3149378bbe2ead08c84 GIT binary patch literal 166 zcmWIWW@h1H00EuCE;ld(N(cbyqSU0+9NnVS-29SMy^7qN0B=Snc?MkSRiHW*pftK} qE(VAUBZCCPhI22^))il1WHQuoXh)(0yjj^m+8Kc`2}tXKI1B)`b7mydq$iN_o&;-$|mz7uq(%#K}FQks)5?DL;hqN@o#0L)^B%H{udvv6M z#X>Sdq9)c^rquTDoiG3ACM6`KaePR7&fsb2IF;qW6&OWcTllvU*7!M z^K-s^ymoc>iPvjam%cmm^QHp3B5W` z|Kg?!J-uHpF{M(6ue|YhmG71~*!N(+#n(;77r4YXC`-(AkqDT3u;mGRNW&xLlC>v} zbuGx)eDvXbhWs$Ij#eL@tq#8gB22*^hlG}KU@uB&aRUPY8d^D-N&2`$NEB5eB9ur9 zl?T^!4jpK?@aFZ4=P#d0$t-&Q`rFO#XENpUWA}FNxwk9o`MEjwWl{=`{y2D9$yPsJ z*8hI@($x_b>3gQxDCw@8`q4Qi^zBa}-R|d)7Wp3uU2f=e_Fu@CjU9q-IR149>svFg zEnu{6n&{cWcvaHJqt1a?ZyiB2G)_VzIN&Kbz#C)$ zuJnsAU`eAX!T>}(fsBHsW{^?x47gH+3fLhGz%0SQpa;wxP`7~62N#0^Sdx)JfX?AA2T0oiB^ek1F;EPD diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb index 48794f0f9e..449c6557c9 100644 --- a/spec/java_buildpack/framework/jrebel_agent_spec.rb +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -21,35 +21,48 @@ describe JavaBuildpack::Framework::JrebelAgent do include_context 'component_helper' - it 'does not detect without JRebel config files present' do + it 'does not detect when rebel-remote.xml is not present' do expect(component.detect).to be_nil end - it 'detects with JRebel config files are present', - app_fixture: 'framework_jrebel_app', - cache_fixture: 'stub-jrebel-archive.zip' do + it 'detects when rebel-remote.xml is present in the top-level directory', + app_fixture: 'framework_jrebel_app_simple' do + expect(component.detect).to eq("jrebel-agent=#{version}") + end + + it 'detects when rebel-remote.xml is present in WEB-INF/classes', + app_fixture: 'framework_jrebel_app_war' do expect(component.detect).to eq("jrebel-agent=#{version}") end - it 'downloads JRebel agent JAR', - app_fixture: 'framework_jrebel_app', + it 'detects when rebel-remote.xml is present inside an embedded JAR', + app_fixture: 'framework_jrebel_app_war_with_jar' do + expect(component.detect).to eq("jrebel-agent=#{version}") + end + + it 'downloads the JRebel JAR and the native agent', + app_fixture: 'framework_jrebel_app_simple', cache_fixture: 'stub-jrebel-archive.zip' do component.compile - expect(sandbox + "jrebel_agent-#{version}.jar").to exist + expect(sandbox + 'lib/jrebel.jar').to exist + expect(sandbox + 'lib/libjrebel64.so').to exist + expect(sandbox + 'lib/libjrebel32.so').to exist end - it 'updates JAVA_OPTS', - app_fixture: 'framework_jrebel_app', + it 'adds correct arguments to JAVA_OPTS', + app_fixture: 'framework_jrebel_app_simple', cache_fixture: 'stub-jrebel-archive.zip' do - allow(services).to receive(:find_service).and_return('credentials' => { 'licenseKey' => 'test-license-key' }) + + allow(component).to receive(:architecture).and_return('x86_64') component.release - expect(java_opts).to include("-javaagent:$PWD/.java-buildpack/jrebel_agent/jrebel_agent-#{version}.jar") + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jrebel_agent/lib/libjrebel64.so') expect(java_opts).to include('-Drebel.remoting_plugin=true') - expect(java_opts).to include("-Xbootclasspath/p:$PWD/.java-buildpack/jrebel_agent/jrebel_agent-#{version}.jar") + expect(java_opts).to include('-Drebel.log=true') + expect(java_opts).to include('-Drebel.cloud.platform=cloudfoundry/java-buildpack') end end From 30515fb26f7d1451831d0c3f99f410093fe62c89 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 21 Apr 2015 09:32:47 +0100 Subject: [PATCH 029/812] Enable caching This change enables caching during Travis builds --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6cd43c6747..8b1a5ae813 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ rvm: - 1.9.3-p551 before_script: if [[ $TRAVIS_RUBY_VERSION != '1.9.3-p551' || $TRAVIS_SECURE_ENV_VARS != 'true' ]]; then unset CODECLIMATE_REPO_TOKEN; fi +cache: bundler notifications: slack: secure: TjtH21rnlUlNVu47g+cZSfgI+01RyAZzuMNU1nZskuUMJzf0PHGQAvA9VVVtC5SQiipGg0eB60xIlFN1VW/pYGw5yUcRkuqp9BUywC6CQFpduOc8fyBJ/ZD90Uu3tS/dCc5WCPRA1KPvGgtd6biofBuC/PJ8rMHQO6SVHUxGVvI= From 390f0bc53c143895f6bdd7f48b1eda552b73a478 Mon Sep 17 00:00:00 2001 From: Jarek Gawor Date: Mon, 20 Apr 2015 22:41:34 -0400 Subject: [PATCH 030/812] handle simpler and invalid values for config overrides --- .../util/configuration_utils.rb | 32 +++++++++++------ .../util/configuration_utils_spec.rb | 35 +++++++++++++++++-- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index f06fe18649..ed645aabc4 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -42,17 +42,8 @@ def load(identifier, should_log = true) file = CONFIG_DIRECTORY + "#{identifier}.yml" if file.exist? - configuration = YAML.load_file(file) - logger.debug { "Configuration from #{file}: #{configuration}" } if should_log - user_provided = ENV[environment_variable_name(identifier)] - - if user_provided - YAML.load(user_provided).each do |new_prop| - configuration = do_merge(configuration, new_prop, should_log) - end - logger.debug { "Configuration from #{file} modified with: #{user_provided}" } if should_log - end + configuration = load_configuration(file, user_provided, should_log) else logger.debug { "No configuration file #{file} found" } if should_log end @@ -68,6 +59,27 @@ def load(identifier, should_log = true) private_constant :CONFIG_DIRECTORY, :ENVIRONMENT_VARIABLE_PATTERN + def load_configuration(file, user_provided, should_log) + configuration = YAML.load_file(file) + logger.debug { "Configuration from #{file}: #{configuration}" } if should_log + + if user_provided + user_provided_value = YAML.load(user_provided) + if user_provided_value.is_a?(Hash) + configuration = do_merge(configuration, user_provided_value, should_log) + elsif user_provided_value.is_a?(Array) + user_provided_value.each do |new_prop| + configuration = do_merge(configuration, new_prop, should_log) + end + else + fail "User configuration value is not valid: #{user_provided_value}" + end + logger.debug { "Configuration from #{file} modified with: #{user_provided}" } if should_log + end + + configuration + end + def do_merge(hash_v1, hash_v2, should_log) hash_v2.each do |key, value| if hash_v1.key? key diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 2557d1e0b3..4435bb088c 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -34,12 +34,14 @@ before do allow_any_instance_of(Pathname).to receive(:exist?).and_return(true) allow(YAML).to receive(:load_file).and_return('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }) + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.7.1') end it 'load configuration file' do expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }) + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.7.1') end context do @@ -51,7 +53,34 @@ it 'overlays matching environment variables' do expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 3, 'two' => 'dog' } }) + 'bar' => { 'alpha' => { 'one' => 3, 'two' => 'dog' } }, + 'version' => '1.7.1') + end + + end + + context do + + let(:environment) do + { 'JBP_CONFIG_TEST' => 'version: 1.8.+' } + end + + it 'overlays simple matching environment variable' do + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.8.+') + end + + end + + context do + + let(:environment) do + { 'JBP_CONFIG_TEST' => 'version 1.8.+' } + end + + it 'raises an exception when invalid override value is specified' do + expect { described_class.load('test') }.to raise_error(/User configuration value is not valid/) end end From 1bf24ef0ecd2736d2473e2b7209e1161ae846543 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 24 Apr 2015 09:31:20 +0100 Subject: [PATCH 031/812] Containerized Travis This change opts the project into containerized Travis builds. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 8b1a5ae813..2769e72fd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ rvm: before_script: if [[ $TRAVIS_RUBY_VERSION != '1.9.3-p551' || $TRAVIS_SECURE_ENV_VARS != 'true' ]]; then unset CODECLIMATE_REPO_TOKEN; fi cache: bundler +sudo: false notifications: slack: secure: TjtH21rnlUlNVu47g+cZSfgI+01RyAZzuMNU1nZskuUMJzf0PHGQAvA9VVVtC5SQiipGg0eB60xIlFN1VW/pYGw5yUcRkuqp9BUywC6CQFpduOc8fyBJ/ZD90Uu3tS/dCc5WCPRA1KPvGgtd6biofBuC/PJ8rMHQO6SVHUxGVvI= From 7d31c8d8feafdae9eeb3fe35367370445f3ab706 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 16 Apr 2015 15:52:02 +0100 Subject: [PATCH 032/812] Add Introscope Agent Framework This change adds support for user provided Introscope services. [#71584700] --- .idea/.rakeTasks | 2 +- .idea/dictionaries/bhale.xml | 5 + .travis.yml | 2 +- Gemfile.lock | 32 ++--- README.md | 1 + config/components.yml | 1 + config/introscope_agent.yml | 20 ++++ docs/framework-introscope_agent.md | 50 ++++++++ java-buildpack.iml | 28 ++--- .../versioned_dependency_component.rb | 2 +- .../framework/app_dynamics_agent.rb | 29 +++-- .../framework/introscope_agent.rb | 95 +++++++++++++++ .../framework/new_relic_agent.rb | 2 +- .../weight_balancing_memory_heuristic.rb | 4 +- lib/java_buildpack/util/tokenized_version.rb | 4 +- spec/fixtures/stub-introscope-agent.tar.gz | Bin 0 -> 158 bytes .../container/tomcat/tomcat_instance_spec.rb | 6 +- .../framework/app_dynamics_agent_spec.rb | 8 +- .../framework/introscope_agent_spec.rb | 113 ++++++++++++++++++ .../framework/new_relic_agent_spec.rb | 2 +- .../repository/configured_item_spec.rb | 12 +- 21 files changed, 349 insertions(+), 69 deletions(-) create mode 100644 config/introscope_agent.yml create mode 100644 docs/framework-introscope_agent.md create mode 100644 lib/java_buildpack/framework/introscope_agent.rb create mode 100644 spec/fixtures/stub-introscope-agent.tar.gz create mode 100644 spec/java_buildpack/framework/introscope_agent_spec.rb diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index 67bf632628..22e60a5ddf 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index b0b77ac213..716becff78 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -13,6 +13,7 @@ dirname distapplication dnewrelic + enterprisemanager etag extname ffoo @@ -24,6 +25,8 @@ getwd heroku httpok + introscope + isengard javaagent jdk's jres @@ -46,6 +49,7 @@ pathnames permgen pkill + postofficehub progname proto ratpack @@ -61,6 +65,7 @@ scriptdir shellwords simplecov + socketfactory stderr strftime stringifies diff --git a/.travis.yml b/.travis.yml index 2769e72fd3..91867bfbad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: ruby rvm: -- 2.1.5 +- 2.2.2 - 1.9.3-p551 before_script: if [[ $TRAVIS_RUBY_VERSION != '1.9.3-p551' || $TRAVIS_SECURE_ENV_VARS != 'true' ]]; then unset CODECLIMATE_REPO_TOKEN; fi diff --git a/Gemfile.lock b/Gemfile.lock index 7ae761cf3d..36da6e43cc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,53 +1,53 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.3.7) + addressable (2.3.8) ast (2.0.0) astrolabe (1.3.0) parser (>= 2.2.0.pre.3, < 3.0) - codeclimate-test-reporter (0.4.6) + codeclimate-test-reporter (0.4.7) simplecov (>= 0.7.1, < 1.0.0) crack (0.4.2) safe_yaml (~> 1.0.0) diff-lcs (1.2.5) docile (1.1.5) - multi_json (1.10.1) - parser (2.2.0.3) + json (1.8.2) + parser (2.2.2.1) ast (>= 1.1, < 3.0) powerpack (0.1.0) rainbow (2.0.0) rake (10.4.2) - redcarpet (3.2.2) + redcarpet (3.2.3) rspec (3.2.0) rspec-core (~> 3.2.0) rspec-expectations (~> 3.2.0) rspec-mocks (~> 3.2.0) - rspec-core (3.2.1) + rspec-core (3.2.3) rspec-support (~> 3.2.0) - rspec-expectations (3.2.0) + rspec-expectations (3.2.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) rspec-mocks (3.2.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) rspec-support (3.2.2) - rubocop (0.29.1) + rubocop (0.30.1) astrolabe (~> 1.3) - parser (>= 2.2.0.1, < 3.0) + parser (>= 2.2.2.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.4) - rubocop-rspec (1.2.1) - ruby-progressbar (1.7.1) + rubocop-rspec (1.3.0) + ruby-progressbar (1.7.5) rubyzip (1.1.7) safe_yaml (1.0.4) - simplecov (0.9.2) + simplecov (0.10.0) docile (~> 1.1.0) - multi_json (~> 1.0) - simplecov-html (~> 0.9.0) - simplecov-html (0.9.0) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) tee (1.0.0) - webmock (1.20.4) + webmock (1.21.0) addressable (>= 2.3.6) crack (>= 0.3.2) yard (0.8.7.6) diff --git a/README.md b/README.md index 86a8fcb75a..f61b13c2b1 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) + * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) diff --git a/config/components.yml b/config/components.yml index a24db3b07f..991a53a86d 100644 --- a/config/components.yml +++ b/config/components.yml @@ -33,6 +33,7 @@ jres: frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" + - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::JavaOpts" - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::MariaDbJDBC" diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml new file mode 100644 index 0000000000..a3e61596fc --- /dev/null +++ b/config/introscope_agent.yml @@ -0,0 +1,20 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the CA Wily framework +--- +repository_root: "" +version: 9.7.+ +default_agent_name: "$(expr \"$VCAP_APPLICATION\" : \'.*application_name[\": ]*\\([A-Za-z0-9_-]*\\).*\')" diff --git a/docs/framework-introscope_agent.md b/docs/framework-introscope_agent.md new file mode 100644 index 0000000000..85a7222dca --- /dev/null +++ b/docs/framework-introscope_agent.md @@ -0,0 +1,50 @@ +# Introscope Agent Framework +The Introscope Agent Framework causes an application to be automatically configured to work with a bound [Introscope service][]. + + + + + + + + + +
Detection CriterionExistence of a single bound Introscope service. +
    +
  • Existence of a Introscope service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has introscope as a substring.
  • +
+
Tagsintroscope-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service (Optional) +Users may optionally provide their own Introscope service. A user-provided Introscope service must have a name or tag with `introscope` in it so that the Introscope Agent Framework will automatically configure the application to work with the service. + +The credential payload of the service may contain the following entries: + +| Name | Description +| ---- | ----------- +| `agent-name` | (Optional) The name that should be given to this instance of the Introscope agent +| `host-name` | The host name of the Introscope Enterprise Manager server +| `ssl` | (Optional) Whether or not to use an SSL connection to the Introscope Enterprise Manager server +| `port` | (Optional) The port of the Introscope Enterprise Manager server + +To provide more complex values such as the `agent-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `agent-name` could be set with a value of `agent-$(expr "$VCAP_APPLICATION" : '.*application_name[": ]*\([[:word:]]*\).*')` to calculate a value from the Cloud Foundry application name. + +## Configuration +For general information on configuring the buildpack, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/introscope_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Introscope Agent repository index ([details][repositories]). +| `version` | The version of Introscope Agent to use. + +### Additional Resources +The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/ca_wily_agent` directory in the buildpack fork. For example, to override the default profile add your custom profile to `resources/introscope_agent/`. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[`config/intoscope_agent.yml`]: ../config/intoscope_agent.yml +[Introscope service]: http://www.ca.com/us/opscenter/ca-application-performance-management.aspx +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/java-buildpack.iml b/java-buildpack.iml index b55473fc29..961716e8b0 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -268,34 +268,34 @@ - + - - + + - - + + - + - - + + - - - + + + - - + + - + diff --git a/lib/java_buildpack/component/versioned_dependency_component.rb b/lib/java_buildpack/component/versioned_dependency_component.rb index 792d0ab777..5433931ef3 100644 --- a/lib/java_buildpack/component/versioned_dependency_component.rb +++ b/lib/java_buildpack/component/versioned_dependency_component.rb @@ -65,7 +65,7 @@ def supports? # @param [Pathname] target_directory the directory to store the JAR file in. Defaults to the component's sandbox. # @param [String] name an optional name for the download. Defaults to +@component_name+. # @return [Void] - def download_jar(jar_name = jar_name, target_directory = @droplet.sandbox, name = @component_name) + def download_jar(jar_name = self.jar_name, target_directory = @droplet.sandbox, name = @component_name) super(@version, @uri, jar_name, target_directory, name) end diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index df9b583ee6..dfcaaf81c1 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -36,14 +36,14 @@ def release java_opts = @droplet.java_opts java_opts.add_javaagent(@droplet.sandbox + 'javaagent.jar') - application_name(java_opts, credentials) - tier_name(java_opts, credentials) - node_name(java_opts, credentials) - account_access_key(java_opts, credentials) - account_name(java_opts, credentials) - host_name(java_opts, credentials) - port(java_opts, credentials) - ssl_enabled(java_opts, credentials) + application_name java_opts, credentials + tier_name java_opts, credentials + node_name java_opts, credentials + account_access_key java_opts, credentials + account_name java_opts, credentials + host_name java_opts, credentials + port java_opts, credentials + ssl_enabled java_opts, credentials end protected @@ -60,10 +60,9 @@ def supports? private_constant :FILTER def application_name(java_opts, credentials) - name = credentials.key?('application-name') ? credentials['application-name'] : - @configuration['default_application_name'] - name = name ? name : @application.details['application_name'] - java_opts.add_system_property('appdynamics.agent.applicationName', "'#{name}'") + name = credentials['application-name'] || @configuration['default_application_name'] || + @application.details['application_name'] + java_opts.add_system_property('appdynamics.agent.applicationName', "#{name}") end def account_access_key(java_opts, credentials) @@ -83,7 +82,7 @@ def host_name(java_opts, credentials) end def node_name(java_opts, credentials) - name = credentials.key?('node-name') ? credentials['node-name'] : @configuration['default_node_name'] + name = credentials['node-name'] || @configuration['default_node_name'] java_opts.add_system_property('appdynamics.agent.nodeName', "#{name}") end @@ -98,8 +97,8 @@ def ssl_enabled(java_opts, credentials) end def tier_name(java_opts, credentials) - name = credentials.key?('tier-name') ? credentials['tier-name'] : @configuration['default_tier_name'] - java_opts.add_system_property('appdynamics.agent.tierName', "'#{name}'") + name = credentials['tier-name'] || @configuration['default_tier_name'] + java_opts.add_system_property('appdynamics.agent.tierName', "#{name}") end end diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb new file mode 100644 index 0000000000..88444284fc --- /dev/null +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -0,0 +1,95 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/to_b' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Introscope support. + class IntroscopeAgent < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_tar + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + credentials = @application.services.find_service(FILTER)['credentials'] + java_opts = @droplet.java_opts + java_opts.add_javaagent(@droplet.sandbox + 'Agent.jar') + java_opts.add_system_property('com.wily.introscope.agentProfile', + @droplet.sandbox + 'core/config/IntroscopeAgent.profile') + + agent_host_name java_opts + agent_name java_opts, credentials + default_process_name java_opts + host_name java_opts, credentials + port java_opts, credentials + ssl_socket_factory java_opts, credentials + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, 'host-name' + end + + private + + FILTER = /introscope/.freeze + + private_constant :FILTER + + def agent_host_name(java_opts) + java_opts.add_system_property('introscope.agent.hostName', @application.details['application_uris'][0]) + end + + def agent_name(java_opts, credentials) + name = credentials['agent-name'] || @configuration['default_agent_name'] + java_opts.add_system_property('com.wily.introscope.agent.agentName', "#{name}") + end + + def default_process_name(java_opts) + java_opts.add_system_property('introscope.agent.defaultProcessName', @application.details['application_name']) + end + + def host_name(java_opts, credentials) + host_name = credentials['host-name'] + fail "'host-name' credential must be set" unless host_name + java_opts.add_system_property 'introscope.agent.enterprisemanager.transport.tcp.host.DEFAULT', host_name + end + + def port(java_opts, credentials) + port = credentials['port'] + java_opts.add_system_property 'introscope.agent.enterprisemanager.transport.tcp.port.DEFAULT', port if port + end + + def ssl_socket_factory(java_opts, credentials) + ssl = credentials['ssl'].to_b + java_opts.add_system_property 'introscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT', + 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory' if ssl + end + + end + end +end diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index ad3405168e..18dc645a6e 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -37,7 +37,7 @@ def release .add_javaagent(@droplet.sandbox + jar_name) .add_system_property('newrelic.home', @droplet.sandbox) .add_system_property('newrelic.config.license_key', license_key) - .add_system_property('newrelic.config.app_name', "'#{application_name}'") + .add_system_property('newrelic.config.app_name', "#{application_name}") .add_system_property('newrelic.config.log_file_path', logs_dir) @droplet.java_opts.add_system_property('newrelic.enable.java.8', 'true') if java_8? end diff --git a/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb b/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb index 3ee50f793c..46abf6cce5 100644 --- a/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb +++ b/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb @@ -234,9 +234,9 @@ def check_close_to_default(type, bucket, total_weighting) end def switches(buckets) - buckets.map do |type, bucket| + buckets.flat_map do |type, bucket| @java_opts[type][bucket.size] if bucket.size && bucket.size > 0 && @java_opts.key?(type) - end.flatten(1).compact + end.compact end end diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index ef6aa77510..de8b325817 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -50,7 +50,7 @@ def <=>(other) i = 0 while comparison == 0 && i < 3 comparison = self[i].to_i <=> other[i].to_i - i += 1 + i += 1 end comparison = qualifier_compare(non_nil_qualifier(self[3]), non_nil_qualifier(other[3])) if comparison == 0 @@ -124,7 +124,7 @@ def qualifier_compare(a, b) i = 0 until comparison != 0 || i == minimum_qualifier_length(a, b) comparison = char_compare(a[i], b[i]) - i += 1 + i += 1 end comparison = a.length <=> b.length if comparison == 0 diff --git a/spec/fixtures/stub-introscope-agent.tar.gz b/spec/fixtures/stub-introscope-agent.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a36a9f9ddd9f749a1acf3342129a231d8f54ff0a GIT binary patch literal 158 zcmb2|=3wZ0Y!J%8{PvK<=Z_>A2(gSeeK7*GA}%m_6M)sfWtmtW~@ zV^O!T_-yBigJ/) expect((sandbox + 'conf/server.xml').read) - .to match(//) + .to match(%r{}) end context do @@ -66,9 +66,9 @@ cache_fixture: 'stub-tomcat.tar.gz' do component.compile - expect((sandbox + 'conf/context.xml').read).to match(/[\s]*/) + expect((sandbox + 'conf/context.xml').read).to match(%r{[\s]*}) expect((sandbox + 'conf/server.xml').read) - .not_to match(//) + .not_to match(%r{}) end end diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 6d4519c696..632fbd2d34 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -64,8 +64,8 @@ expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/app_dynamics_agent/javaagent.jar') expect(java_opts).to include('-Dappdynamics.controller.hostName=test-host-name') - expect(java_opts).to include("-Dappdynamics.agent.applicationName='test-application-name'") - expect(java_opts).to include("-Dappdynamics.agent.tierName='test-tier-name'") + expect(java_opts).to include('-Dappdynamics.agent.applicationName=test-application-name') + expect(java_opts).to include('-Dappdynamics.agent.tierName=test-tier-name') expect(java_opts).to include('-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : ' \ '\'.*instance_index[": ]*\\([[:digit:]]*\\).*\')') end @@ -76,7 +76,7 @@ it 'adds tier_name from credentials to JAVA_OPTS if specified' do component.release - expect(java_opts).to include("-Dappdynamics.agent.tierName='another-test-tier-name'") + expect(java_opts).to include('-Dappdynamics.agent.tierName=another-test-tier-name') end end @@ -86,7 +86,7 @@ it 'adds application_name from credentials to JAVA_OPTS if specified' do component.release - expect(java_opts).to include("-Dappdynamics.agent.applicationName='another-test-application-name'") + expect(java_opts).to include('-Dappdynamics.agent.applicationName=another-test-application-name') end end diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb new file mode 100644 index 0000000000..5df424ca7c --- /dev/null +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -0,0 +1,113 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/introscope_agent' + +describe JavaBuildpack::Framework::IntroscopeAgent do + include_context 'component_helper' + + let(:configuration) do + { 'default_agent_name' => "$(expr \"$VCAP_APPLICATION\" : '.*application_name[\": ]*\\([A-Za-z0-9_-]*\\).*')" } + end + + let(:vcap_application) do + { 'application_name' => 'test-application-name', + 'application_uris' => %w(test-application-uri-0 test-application-uri-1) } + end + + it 'does not detect without introscope-n/a service' do + expect(component.detect).to be_nil + end + + context do + + let(:credentials) { {} } + + before do + allow(services).to receive(:one_service?).with(/introscope/, 'host-name').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => credentials) + end + + it 'detects with introscope-n/a service' do + expect(component.detect).to eq("introscope-agent=#{version}") + end + + it 'expands Introscope agent zip', + cache_fixture: 'stub-introscope-agent.tar.gz' do + + component.compile + + expect(sandbox + 'Agent.jar').to exist + end + + it 'raises error if host-name not specified' do + expect { component.release }.to raise_error(/'host-name' credential must be set/) + end + + context do + + let(:credentials) { { 'host-name' => 'test-host-name' } } + + it 'updates JAVA_OPTS' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + end + + context do + let(:credentials) { super().merge 'agent-name' => 'another-test-agent-name' } + + it 'adds agent-name from credentials to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=another-test-agent-name') + end + end + + context do + let(:credentials) { super().merge 'port' => 'test-port' } + + it 'adds port from credentials to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=test-port') + end + end + + context do + let(:credentials) { super().merge 'ssl' => 'true' } + + it 'adds ssl socket factory from credentials to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') + end + end + end + + end + +end diff --git a/spec/java_buildpack/framework/new_relic_agent_spec.rb b/spec/java_buildpack/framework/new_relic_agent_spec.rb index 3acd1593df..355dd8045d 100644 --- a/spec/java_buildpack/framework/new_relic_agent_spec.rb +++ b/spec/java_buildpack/framework/new_relic_agent_spec.rb @@ -59,7 +59,7 @@ expect(java_opts).to include("-javaagent:$PWD/.java-buildpack/new_relic_agent/new_relic_agent-#{version}.jar") expect(java_opts).to include('-Dnewrelic.home=$PWD/.java-buildpack/new_relic_agent') expect(java_opts).to include('-Dnewrelic.config.license_key=test-license-key') - expect(java_opts).to include("-Dnewrelic.config.app_name='test-application-name'") + expect(java_opts).to include('-Dnewrelic.config.app_name=test-application-name') expect(java_opts).to include('-Dnewrelic.config.log_file_path=$PWD/.java-buildpack/new_relic_agent/logs') end diff --git a/spec/java_buildpack/repository/configured_item_spec.rb b/spec/java_buildpack/repository/configured_item_spec.rb index 523da8479f..c86c9b5e01 100644 --- a/spec/java_buildpack/repository/configured_item_spec.rb +++ b/spec/java_buildpack/repository/configured_item_spec.rb @@ -39,8 +39,7 @@ details = described_class.find_item('Test', 'repository_root' => 'test-repository-root', 'java.runtime.version' => 'test-java-runtime-version', - 'version' => '1.7.0' - ) + 'version' => '1.7.0') expect(details[0]).to eq(resolved_version) expect(details[1]).to eq(resolved_uri) @@ -49,8 +48,7 @@ it 'resolves a configuration version if specified' do details = described_class.find_item('Test', 'repository_root' => 'test-repository-root', - 'version' => '1.7.0' - ) + 'version' => '1.7.0') expect(details[0]).to eq(resolved_version) expect(details[1]).to eq(resolved_uri) @@ -59,16 +57,14 @@ it 'drives the version validator block if supplied' do described_class.find_item('Test', 'repository_root' => 'test-repository-root', - 'version' => '1.7.0' - ) do |version| + 'version' => '1.7.0') do |version| expect(version).to eq(JavaBuildpack::Util::TokenizedVersion.new('1.7.0')) end end it 'resolves nil if no version is specified' do details = described_class.find_item('Test', - 'repository_root' => 'test-repository-root' - ) + 'repository_root' => 'test-repository-root') expect(details[0]).to eq(resolved_version) expect(details[1]).to eq(resolved_uri) From ec765d1a5315b7c430eea9949ce609c90443b22a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 27 Apr 2015 15:48:30 +0100 Subject: [PATCH 033/812] Update Introscope Tests This change updates the Introscope tests to use a fixture that looks like what comes directly from CA. This means that the stub agent has a wily/ root directory and is not gzipped. --- java-buildpack.iml | 4 ++-- spec/fixtures/stub-introscope-agent.tar | Bin 0 -> 2048 bytes spec/fixtures/stub-introscope-agent.tar.gz | Bin 158 -> 0 bytes .../framework/introscope_agent_spec.rb | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 spec/fixtures/stub-introscope-agent.tar delete mode 100644 spec/fixtures/stub-introscope-agent.tar.gz diff --git a/java-buildpack.iml b/java-buildpack.iml index 961716e8b0..93836390cb 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -287,8 +287,8 @@ - - + + diff --git a/spec/fixtures/stub-introscope-agent.tar b/spec/fixtures/stub-introscope-agent.tar new file mode 100644 index 0000000000000000000000000000000000000000..4e95eecd73c46339a1b15fede9ba65f958cabaaa GIT binary patch literal 2048 zcmXTV%&F98pe-;kFfcbYRbT+oW)RxI$OOy>3W0%wp^>SfxrvFXiHU)NfuWI+nHhtE zDQ%qvF}<|7B(VtSw4{v0oK!p(0+pqu;gN^>1LR2{P{5;dP)U`8;@>enHLpZ33m6VG q0l@GuGl9f6k@0V0U}(UgU_cYspcy*C;~yK<=Z_>A2(gSeeK7*GA}%m_6M)sfWtmtW~@ zV^O!T_-yBigJ Date: Mon, 27 Apr 2015 15:58:48 +0100 Subject: [PATCH 034/812] Tar flags This change makes the flags in the untar command conditional on whether the binary is actually gzipped. On Linux (unlike OS X), using the z flag causes a failure if the file isn't actually gzipped. --- lib/java_buildpack/component/base_component.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 7617382512..8953337ba8 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -121,7 +121,7 @@ def download_tar(version, uri, target_directory = @droplet.sandbox, name = @comp download(version, uri, name) do |file| with_timing "Expanding #{name} to #{target_directory.relative_path_from(@droplet.root)}" do FileUtils.mkdir_p target_directory - shell "tar xzf #{file.path} -C #{target_directory} --strip 1 2>&1" + shell "tar x#{gzipped?(file) ? 'x' : ''}f #{file.path} -C #{target_directory} --strip 1 2>&1" end end end @@ -165,6 +165,12 @@ def with_timing(caption) puts "(#{(Time.now - start_time).duration})" end + private + + def gzipped?(file) + file.path.end_with? '.gz' + end + end end From 528894ae40d830f1a0a225659e0d0b86b588ab61 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 1 May 2015 14:06:56 +0100 Subject: [PATCH 035/812] Disable Introscope Agent Framework Previously, the Introscope Agent Framework was enabled by default. Since there is no repository where the Introscope can be downloaded, attempting to package while it was enabled caused a failure. This change makes no code changes, but disables the framework by default. The documentation has also been updated to reflect this fact. [resolves #180] --- config/components.yml | 2 +- docs/framework-introscope_agent.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/components.yml b/config/components.yml index 991a53a86d..3612c67cb4 100644 --- a/config/components.yml +++ b/config/components.yml @@ -33,7 +33,7 @@ jres: frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" - - "JavaBuildpack::Framework::IntroscopeAgent" +# - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::JavaOpts" - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::MariaDbJDBC" diff --git a/docs/framework-introscope_agent.md b/docs/framework-introscope_agent.md index 85a7222dca..1b82225903 100644 --- a/docs/framework-introscope_agent.md +++ b/docs/framework-introscope_agent.md @@ -1,5 +1,5 @@ # Introscope Agent Framework -The Introscope Agent Framework causes an application to be automatically configured to work with a bound [Introscope service][]. +The Introscope Agent Framework causes an application to be automatically configured to work with a bound [Introscope service][]. **Note:** This framework is disabled by default. From f64e9f8a6eb3036079e5cdbdf2f5ce77e26ad7bc Mon Sep 17 00:00:00 2001 From: Stuart Charlton Date: Mon, 4 May 2015 16:51:29 -0600 Subject: [PATCH 036/812] Ensure that web.xml adds servlet init-params before any load-on-startup element --- .../web_xml_modifier.rb | 9 +++++++-- ...eb_servlet_existing_load_on_startup_after.xml | 14 ++++++++++++++ ...b_servlet_existing_load_on_startup_before.xml | 16 ++++++++++++++++ .../web_servlet_load_on_startup_after.xml | 14 ++++++++++++++ .../web_servlet_load_on_startup_before.xml | 8 ++++++++ .../web_xml_modifier_spec.rb | 2 ++ 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/web_servlet_existing_load_on_startup_after.xml create mode 100644 spec/fixtures/web_servlet_existing_load_on_startup_before.xml create mode 100644 spec/fixtures/web_servlet_load_on_startup_after.xml create mode 100644 spec/fixtures/web_servlet_load_on_startup_before.xml diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb index 4099bd0947..a58c63a4f9 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb @@ -95,8 +95,13 @@ def context_loader_listener? end def create_param(root, param_type, name, value) - param = REXML::Element.new param_type, root - + load_on_startup = xpath(root, 'load-on-startup') + if load_on_startup.any? + param = REXML::Element.new param_type + load_on_startup.first.previous_sibling = param + else + param = REXML::Element.new param_type, root + end param_name = REXML::Element.new 'param-name', param REXML::Text.new name, true, param_name diff --git a/spec/fixtures/web_servlet_existing_load_on_startup_after.xml b/spec/fixtures/web_servlet_existing_load_on_startup_after.xml new file mode 100644 index 0000000000..acc6828b0d --- /dev/null +++ b/spec/fixtures/web_servlet_existing_load_on_startup_after.xml @@ -0,0 +1,14 @@ + + + + test + org.springframework.web.servlet.DispatcherServlet + + contextInitializerClasses + + com.gopivotal.test,org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + + + 1 + + diff --git a/spec/fixtures/web_servlet_existing_load_on_startup_before.xml b/spec/fixtures/web_servlet_existing_load_on_startup_before.xml new file mode 100644 index 0000000000..4f824c19de --- /dev/null +++ b/spec/fixtures/web_servlet_existing_load_on_startup_before.xml @@ -0,0 +1,16 @@ + + + + test + org.springframework.web.servlet.DispatcherServlet + + + contextInitializerClasses + + + com.gopivotal.test + + + 1 + + diff --git a/spec/fixtures/web_servlet_load_on_startup_after.xml b/spec/fixtures/web_servlet_load_on_startup_after.xml new file mode 100644 index 0000000000..7575ac5f28 --- /dev/null +++ b/spec/fixtures/web_servlet_load_on_startup_after.xml @@ -0,0 +1,14 @@ + + + + test + org.springframework.web.servlet.DispatcherServlet + + contextInitializerClasses + + org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + + + 1 + + diff --git a/spec/fixtures/web_servlet_load_on_startup_before.xml b/spec/fixtures/web_servlet_load_on_startup_before.xml new file mode 100644 index 0000000000..593fc44357 --- /dev/null +++ b/spec/fixtures/web_servlet_load_on_startup_before.xml @@ -0,0 +1,8 @@ + + + + test + org.springframework.web.servlet.DispatcherServlet + 1 + + diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb index 024deb99f1..56929cfa1f 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb @@ -30,11 +30,13 @@ it 'adds a new contextInitializerClasses if it does not exist' do assert_equality('web_root_no_params') { |modifier| modifier.augment_root_context } assert_equality('web_servlet_no_params') { |modifier| modifier.augment_servlet_contexts } + assert_equality('web_servlet_load_on_startup') { |modifier| modifier.augment_servlet_contexts } end it 'updates existing contextInitializerClasses if it does exist' do assert_equality('web_root_existing_params') { |modifier| modifier.augment_root_context } assert_equality('web_servlet_existing_params') { |modifier| modifier.augment_servlet_contexts } + assert_equality('web_servlet_existing_load_on_startup') { |modifier| modifier.augment_servlet_contexts } end def assert_equality(fixture) From 5183eb92fcf6fab91825516a740051997ac7222f Mon Sep 17 00:00:00 2001 From: Christopher Umbel Date: Tue, 5 May 2015 13:50:55 -0400 Subject: [PATCH 037/812] OS Detection and specs work on non-centos and future CentOS versions OS detection specs even on CentOS 6 would fail for non RH OSes. OS detection on CentOS 7 would fail completely due to format changes for /etc/redhat-release. OS detection would like have detected incorrectly on >9 as only a single digit was matched by regex. --- lib/java_buildpack/repository/repository_index.rb | 3 ++- .../repository/repository_index_spec.rb | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 1c764668c4..69f2d0e19c 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -85,7 +85,8 @@ def platform redhat_release = Pathname.new('/etc/redhat-release') if redhat_release.exist? - "centos#{redhat_release.read.match(/CentOS release (\d)/)[1]}" + tokens = redhat_release.read.match(/(\w+) (?:Linux )?release (\d+)/) + "#{tokens[1].downcase}#{tokens[2]}" elsif `uname -s` =~ /Darwin/ 'mountainlion' elsif !`which lsb_release 2> /dev/null`.empty? diff --git a/spec/java_buildpack/repository/repository_index_spec.rb b/spec/java_buildpack/repository/repository_index_spec.rb index 2e4d913dad..9a5d33999e 100644 --- a/spec/java_buildpack/repository/repository_index_spec.rb +++ b/spec/java_buildpack/repository/repository_index_spec.rb @@ -84,6 +84,10 @@ end it 'handles Mac OS X' do + allow(Pathname).to receive(:new).and_call_original + non_redhat = double('non-redhat', exist?: false) + allow(Pathname).to receive(:new).with('/etc/redhat-release').and_return(non_redhat) + allow_any_instance_of(described_class).to receive(:`).with('uname -s').and_return('Darwin') allow_any_instance_of(described_class).to receive(:`).with('uname -m').and_return('x86_64') allow(application_cache).to receive(:get).with('mountainlion/x86_64/test-uri/index.yml') @@ -95,6 +99,10 @@ end it 'handles Ubuntu' do + allow(Pathname).to receive(:new).and_call_original + non_redhat = double('non-redhat', exist?: false) + allow(Pathname).to receive(:new).with('/etc/redhat-release').and_return(non_redhat) + allow_any_instance_of(described_class).to receive(:`).with('uname -s').and_return('Linux') allow_any_instance_of(described_class).to receive(:`).with('uname -m').and_return('x86_64') allow_any_instance_of(described_class).to receive(:`).with('which lsb_release 2> /dev/null') @@ -109,6 +117,10 @@ end it 'handles unknown OS' do + allow(Pathname).to receive(:new).and_call_original + non_redhat = double('non-redhat', exist?: false) + allow(Pathname).to receive(:new).with('/etc/redhat-release').and_return(non_redhat) + allow_any_instance_of(File).to receive(:exists?).with('/etc/redhat-release').and_return(false) allow_any_instance_of(described_class).to receive(:`).with('uname -s').and_return('Linux') allow_any_instance_of(described_class).to receive(:`).with('which lsb_release 2> /dev/null').and_return('') From 9393dc1a8262686769f342bc02c1e696c8253374 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 30 Apr 2015 13:46:33 +0100 Subject: [PATCH 038/812] JRE Memory Calculator Previously the values for the applications memory regions were calculated once during staging. If the application was scaled such that the amount of memory allocated to it changed, the application had to be restaged in order to recalculate how the memory was allocated. Customers claimed that this slowed down development cycles and the behavior should be modified such that only a restart was required. This change incorporates a native executable to calculate the memory region allocation. This executable is run during staging to ensure that the initial memory size and heuristics are valid. The executable is then run as a subshell each time the application is started. This means that when the memory size is changed and the application is restarted, the memory allocations are adjusted accordingly. If the new memory size causes an illegal allocation of memory, startup will fail. [#93606820] --- .idea/dictionaries/bhale.xml | 1 + Gemfile.lock | 6 +- config/open_jdk_jre.yml | 26 +- config/oracle_jre.yml | 26 +- java-buildpack.iml | 8 +- lib/java_buildpack/buildpack.rb | 9 +- .../component/base_component.rb | 5 +- .../component/immutable_java_home.rb | 9 +- lib/java_buildpack/component/java_opts.rb | 24 +- .../component/mutable_java_home.rb | 15 +- lib/java_buildpack/container/tomcat.rb | 1 + .../framework/new_relic_agent.rb | 6 +- .../jre/memory/memory_bucket.rb | 93 ---- lib/java_buildpack/jre/memory/memory_limit.rb | 46 -- lib/java_buildpack/jre/memory/memory_range.rb | 138 ------ lib/java_buildpack/jre/memory/memory_size.rb | 166 ------- .../openjdk_memory_heuristic_factory.rb | 64 --- .../jre/memory/stack_memory_bucket.rb | 53 --- .../weight_balancing_memory_heuristic.rb | 245 ---------- lib/java_buildpack/jre/open_jdk_like.rb | 79 +--- lib/java_buildpack/jre/open_jdk_like_jre.rb | 70 +++ .../jre/open_jdk_like_memory_calculator.rb | 108 +++++ .../util/cache/download_cache.rb | 12 +- .../util/cache/internet_availability.rb | 2 +- lib/java_buildpack/util/tokenized_version.rb | 6 +- spec/application_helper.rb | 8 +- spec/fixtures/stub-memory-calculator | 0 spec/integration_helper.rb | 8 +- .../component/immutable_java_home_spec.rb | 12 +- .../component/mutable_java_home_spec.rb | 23 +- spec/java_buildpack/container/tomcat_spec.rb | 1 - .../framework/new_relic_agent_spec.rb | 4 +- .../jre/memory/memory_bucket_spec.rb | 59 --- .../jre/memory/memory_limit_spec.rb | 79 ---- .../jre/memory/memory_range_spec.rb | 161 ------- .../jre/memory/memory_size_spec.rb | 138 ------ .../openjdk_memory_heuristic_factory_spec.rb | 67 --- .../jre/memory/stack_memory_bucket_spec.rb | 37 -- .../weight_balancing_memory_heuristic_spec.rb | 440 ------------------ spec/java_buildpack/jre/open_jdk_jre_spec.rb | 126 ----- ..._jre_spec.rb => open_jdk_like_jre_spec.rb} | 42 +- .../open_jdk_like_memory_calculator_spec.rb | 102 ++++ spec/java_buildpack/jre/open_jdk_like_spec.rb | 85 ++++ 43 files changed, 545 insertions(+), 2065 deletions(-) delete mode 100644 lib/java_buildpack/jre/memory/memory_bucket.rb delete mode 100644 lib/java_buildpack/jre/memory/memory_limit.rb delete mode 100644 lib/java_buildpack/jre/memory/memory_range.rb delete mode 100644 lib/java_buildpack/jre/memory/memory_size.rb delete mode 100644 lib/java_buildpack/jre/memory/openjdk_memory_heuristic_factory.rb delete mode 100644 lib/java_buildpack/jre/memory/stack_memory_bucket.rb delete mode 100644 lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb create mode 100644 lib/java_buildpack/jre/open_jdk_like_jre.rb create mode 100644 lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb create mode 100644 spec/fixtures/stub-memory-calculator delete mode 100644 spec/java_buildpack/jre/memory/memory_bucket_spec.rb delete mode 100644 spec/java_buildpack/jre/memory/memory_limit_spec.rb delete mode 100644 spec/java_buildpack/jre/memory/memory_range_spec.rb delete mode 100644 spec/java_buildpack/jre/memory/memory_size_spec.rb delete mode 100644 spec/java_buildpack/jre/memory/openjdk_memory_heuristic_factory_spec.rb delete mode 100644 spec/java_buildpack/jre/memory/stack_memory_bucket_spec.rb delete mode 100644 spec/java_buildpack/jre/memory/weight_balancing_memory_heuristic_spec.rb delete mode 100644 spec/java_buildpack/jre/open_jdk_jre_spec.rb rename spec/java_buildpack/jre/{oracle_jre_spec.rb => open_jdk_like_jre_spec.rb} (61%) create mode 100644 spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb create mode 100644 spec/java_buildpack/jre/open_jdk_like_spec.rb diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 716becff78..00373e0290 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -50,6 +50,7 @@ permgen pkill postofficehub + preformatted progname proto ratpack diff --git a/Gemfile.lock b/Gemfile.lock index 36da6e43cc..17a69d946d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,9 +12,9 @@ GEM diff-lcs (1.2.5) docile (1.1.5) json (1.8.2) - parser (2.2.2.1) + parser (2.2.2.2) ast (>= 1.1, < 3.0) - powerpack (0.1.0) + powerpack (0.1.1) rainbow (2.0.0) rake (10.4.2) redcarpet (3.2.3) @@ -31,7 +31,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) rspec-support (3.2.2) - rubocop (0.30.1) + rubocop (0.31.0) astrolabe (~> 1.3) parser (>= 2.2.2.1, < 3.0) powerpack (~> 0.1) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 7358095fac..a42e8a72c1 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -16,14 +16,18 @@ # Configuration for JRE repositories keyed by vendor # If Java 7 is required, permgen will be used instead of metaspace. Please see the documentation for more detail. --- -repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" -version: 1.8.0_+ -memory_sizes: - metaspace: 64m.. - permgen: 64m.. -memory_heuristics: - heap: 75 - metaspace: 10 - permgen: 10 - stack: 5 - native: 10 +jre: + version: 1.8.0_+ + repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" +memory_calculator: + version: 1.+ + repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + memory_sizes: + metaspace: 64m.. + permgen: 64m.. + memory_heuristics: + heap: 75 + metaspace: 10 + permgen: 10 + stack: 5 + native: 10 diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index e4d46efc82..d7591ad095 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -19,14 +19,18 @@ # You must specify a the repository root of an Oracle JRE repository. Please see the documentation for more detail. # e.g. repository_root: "http://example.com/oracle-jre/{platform}/{architecture}" -repository_root: "" -version: 1.8.0_+ -memory_sizes: - metaspace: 64m.. -# permgen: 64m.. -memory_heuristics: - heap: 75 - metaspace: 10 -# permgen: 10 - stack: 5 - native: 10 +jre: + version: 1.8.0_+ + repository_root: "" +memory_calculator: + version: 1.+ + repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + memory_sizes: + metaspace: 64m.. + permgen: 64m.. + memory_heuristics: + heap: 75 + metaspace: 10 + permgen: 10 + stack: 5 + native: 10 diff --git a/java-buildpack.iml b/java-buildpack.iml index 93836390cb..a047a3fd77 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -271,14 +271,14 @@ - + - - + + @@ -287,7 +287,7 @@ - + diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 229afa39aa..84ee132ed5 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -72,14 +72,15 @@ def release container = component_detection('container', @containers, true).first fail 'No container can run this application' unless container - component_detection('JRE', @jres, true).first.release - component_detection('framework', @frameworks, false).each(&:release) - command = container.release + commands = [] + commands << component_detection('JRE', @jres, true).first.release + component_detection('framework', @frameworks, false).map(&:release) + commands << container.release payload = { 'addons' => [], 'config_vars' => {}, - 'default_process_types' => { 'web' => command } + 'default_process_types' => { 'web' => commands.flatten.compact.join(' && ') } }.to_yaml @logger.debug { "Release Payload:\n#{payload}" } diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 8953337ba8..e5d968108d 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -69,8 +69,9 @@ def compile # Container components are also expected to create the command required to run the application. These components # are expected to read the +context+ values and take them into account when creating the command. # - # @return [void, String] components other than containers are not expected to return any value. Container - # components are expected to return the command required to run the application. + # @return [void, String] components other than containers and JREs are not expected to return any value. + # Container and JRE components are expected to return a command required to run the + # application. def release fail "Method 'release' must be defined" end diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index 9a19f54da6..afcf3bd6df 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -42,12 +42,19 @@ def as_env_var "JAVA_HOME=#{root}" end + # Whether or not the version of Java is 8 or later + # + # @return [Boolean] +true+ iff the version is 1.8.0 or later + def java_8_or_later? + @delegate.java_8_or_later? + end + # @return [String] the root of the droplet's +JAVA_HOME+ formatted as +$PWD/+ def root qualify_path @delegate.root end - # @return [String] the version of Java being used by the droplet + # @return # @return [JavaBuildpack::Util::TokenizedVersion] the tokenized droplet's +VERSION+ def version @delegate.version end diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index 18d552082a..7041128e78 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -39,8 +39,7 @@ def initialize(droplet_root) # @param [Pathname] path the path to the +javaagent+ JAR # @return [JavaOpts] +self+ for chaining def add_javaagent(path) - self << "-javaagent:#{qualify_path path}" - self + add_preformatted_options "-javaagent:#{qualify_path path}" end # Adds an +agentpath+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to @@ -49,8 +48,7 @@ def add_javaagent(path) # @param [Pathname] path the path to the +native+ +agent+ # @return [JavaOpts] +self+ for chaining def add_agentpath(path) - self << "-agentpath:#{qualify_path path}" - self + add_preformatted_options "-agentpath:#{qualify_path path}" end # Adds a +bootclasspath/p+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to @@ -59,8 +57,7 @@ def add_agentpath(path) # @param [Pathname] path the path to the +javaagent+ JAR # @return [JavaOpts] +self+ for chaining def add_bootclasspath_p(path) - self << "-Xbootclasspath/p:#{qualify_path path}" - self + add_preformatted_options "-Xbootclasspath/p:#{qualify_path path}" end # Adds a system property to the +JAVA_OPTS+. Ensures that the key is prepended with +-D+. If the value is a @@ -71,8 +68,7 @@ def add_bootclasspath_p(path) # @param [Pathname, String] value the value of the system property # @return [JavaOpts] +self+ for chaining def add_system_property(key, value) - self << "-D#{key}=#{qualify_value(value)}" - self + add_preformatted_options "-D#{key}=#{qualify_value(value)}" end # Adds an option to the +JAVA_OPTS+. Nothing is prepended to the key. If the value is a +Pathname+, then @@ -80,10 +76,18 @@ def add_system_property(key, value) # Otherwise, uses the value as-is. # # @param [String] key the key of the option - # @param [Pathname, String] value the value of the system property + # @param [Pathname, String] value the value of the option # @return [JavaOpts] +self+ for chaining def add_option(key, value) - self << "#{key}=#{qualify_value(value)}" + add_preformatted_options "#{key}=#{qualify_value(value)}" + end + + # Adds a preformatted option to the +JAVA_OPTS+ + # + # @param [String] value the value of options + # @return [JavaOpts] +self+ for chaining + def add_preformatted_options(value) + self << value self end diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index 8c8d575c3a..6092f5f48f 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -15,6 +15,7 @@ # limitations under the License. require 'java_buildpack/component' +require 'java_buildpack/util/tokenized_version' module JavaBuildpack module Component @@ -30,9 +31,21 @@ class MutableJavaHome attr_accessor :root # @!attribute [rw] version - # @return [Array] the major, minor, micro and qualifier of the droplet's +VERSION+ + # @return [JavaBuildpack::Util::TokenizedVersion] the tokenized droplet's +VERSION+ attr_accessor :version + # Whether or not the version of Java is 8 or later + # @return [Boolean] +true+ iff the version is 1.8.0 or later + def java_8_or_later? + @version >= VERSION_8 + end + + private + + VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0').freeze + + private_constant :VERSION_8 + end end diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 9f9d56d1c9..82b2f2d3ee 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -23,6 +23,7 @@ require 'java_buildpack/container/tomcat/tomcat_access_logging_support' require 'java_buildpack/container/tomcat/tomcat_redis_store' require 'java_buildpack/container/tomcat/tomcat_gemfire_store' +require 'java_buildpack/util/java_main_utils' module JavaBuildpack module Container diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 18dc645a6e..c02a46576c 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -39,7 +39,7 @@ def release .add_system_property('newrelic.config.license_key', license_key) .add_system_property('newrelic.config.app_name', "#{application_name}") .add_system_property('newrelic.config.log_file_path', logs_dir) - @droplet.java_opts.add_system_property('newrelic.enable.java.8', 'true') if java_8? + @droplet.java_opts.add_system_property('newrelic.enable.java.8', 'true') if @droplet.java_home.java_8_or_later? end protected @@ -55,10 +55,6 @@ def supports? private_constant :FILTER - def java_8? - @droplet.java_home.version[1] == '8' - end - def application_name @application.details['application_name'] end diff --git a/lib/java_buildpack/jre/memory/memory_bucket.rb b/lib/java_buildpack/jre/memory/memory_bucket.rb deleted file mode 100644 index dde34aae2a..0000000000 --- a/lib/java_buildpack/jre/memory/memory_bucket.rb +++ /dev/null @@ -1,93 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/logging/logger_factory' -require 'java_buildpack/jre' -require 'java_buildpack/jre/memory/memory_range' - -module JavaBuildpack - module Jre - - # A MemoryBucket is used to calculate default sizes for various type of memory - class MemoryBucket - - # @!attribute [r] size - # @return [Numeric, nil] the size of the memory bucket in KB or nil if this has not been specified by the user or - # defaulted - attr_reader :size - - # @!attribute [r] range - # @return [MemoryRange] the permissible range of the memory bucket - attr_accessor :range - - # @!attribute [r] weighting - # @return [Numeric] the weighting of the memory bucket - attr_reader :weighting - - # Constructs a memory bucket. - # - # @param [String] name a non-empty, human-readable name for this memory bucket, used only in diagnostics - # @param [Numeric] weighting a number between 0 and 1 corresponding to the proportion of total memory which this - # memory bucket should consume by default - # @param [MemoryRange, nil] range a user-specified range for the memory bucket or nil if the user did not specify - # a range - def initialize(name, weighting, range) - @name = validate_name name - @weighting = validate_weighting weighting - @range = range ? validate_memory_range(range) : nil - logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger MemoryBucket - logger.debug { inspect } - end - - attr_writer :size - - private - - def validate_name(name) - fail "Invalid MemoryBucket name '#{name}'" if name.nil? || name.to_s.size == 0 - name - end - - def validate_weighting(weighting) - fail diagnose_weighting(weighting, 'not numeric') unless numeric? weighting - fail diagnose_weighting(weighting, 'negative') if weighting < 0 - weighting - end - - def diagnose_weighting(weighting, reason) - "Invalid weighting '#{weighting}' for #{identify} : #{reason}" - end - - def numeric?(w) - Float(w) rescue false - end - - def identify - "MemoryBucket #{@name}" - end - - def validate_memory_range(range) - unless range.is_a? MemoryRange - fail "Invalid 'range' parameter of class '#{range.class}' for #{identify} : not a MemoryRange" - end - - range - end - - end - - end -end diff --git a/lib/java_buildpack/jre/memory/memory_limit.rb b/lib/java_buildpack/jre/memory/memory_limit.rb deleted file mode 100644 index 9e4f3e98de..0000000000 --- a/lib/java_buildpack/jre/memory/memory_limit.rb +++ /dev/null @@ -1,46 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/jre' -require 'java_buildpack/jre/memory/memory_size' - -module JavaBuildpack - module Jre - - # A utility for handling Java memory settings. - class MemoryLimit - - private_class_method :new - - class << self - - # Returns the application's memory limit. - # - # @return [MemorySize, nil] the application's memory limit or nil if no memory limit has been provided - def memory_limit - memory_limit = ENV['MEMORY_LIMIT'] - return nil unless memory_limit - memory_limit_size = MemorySize.new(memory_limit) - fail "Invalid negative $MEMORY_LIMIT #{memory_limit}" if memory_limit_size < 0 - memory_limit_size - end - - end - - end - - end -end diff --git a/lib/java_buildpack/jre/memory/memory_range.rb b/lib/java_buildpack/jre/memory/memory_range.rb deleted file mode 100644 index cf034e1efc..0000000000 --- a/lib/java_buildpack/jre/memory/memory_range.rb +++ /dev/null @@ -1,138 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/jre' - -module JavaBuildpack - module Jre - - # A class representing a permissible range of memory sizes. - class MemoryRange - - # @!attribute [r] floor - # @return [MemorySize] the lower bound of this memory range - attr_reader :floor - - # @!attribute [r] ceiling - # @return [MemorySize, nil] the upper bound of this memory range or +nil+ if there is no upper bound - attr_reader :ceiling - - # Creates a memory range based on either a memory range string or lower and upper bounds expressed as MemorySizes. - # - # @param [MemorySize, String] value the lower bound of the range or a string range - # @param [MemorySize, nil] ceiling the upper bound of the range - def initialize(value, ceiling = nil) - if value.is_a? String - fail "Invalid combination of parameter types #{value.class} and #{ceiling.class}" if ceiling - lower_bound, upper_bound = get_bounds(value) - @floor = create_memory_size lower_bound - @ceiling = upper_bound ? create_memory_size(upper_bound) : nil - else - validate_memory_size value - validate_memory_size ceiling if ceiling - @floor = value - @ceiling = ceiling - end - fail "Invalid range: floor #{@floor} is higher than ceiling #{@ceiling}" if @ceiling && @floor > @ceiling - end - - # Determines whether or not this range is bounded. Reads better than testing for a +nil+ ceiling. - # - # @return [Boolean] +true+ if and only if this range is bounded - alias_method :bounded?, :ceiling - - # Determines whether a given memory size falls in this range. - # - # @param [MemorySize] size the memory size to be checked - # @return [Boolean] +true+ if and only if the given memory size falls in this range - def contains?(size) - @floor <= size && (@ceiling.nil? || size <= @ceiling) - end - - # Constrains a given memory size to this range. If the size falls within the range, returns the size. - # If the size is below the range, return the floor of the range. If the size is above the range, - # return the ceiling of the range. - # - # @param [MemorySize] size the memory size to be constrained - # @return [MemorySize] the constrained memory size - def constrain(size) - if size < @floor - @floor - else - @ceiling && size > @ceiling ? @ceiling : size - end - end - - # Returns true if and only if this range consists of a single value. - # - # @return [Boolean] whether or not this range consists of a single value - def degenerate? - @floor == @ceiling - end - - # Multiply this memory range by a numeric factor. - # - # @param [Numeric] other the factor to multiply by - # @return [MemoryRange] the result - def *(other) - fail "Cannot multiply a MemoryRange by an instance of #{other.class}" unless other.is_a? Numeric - fail 'Cannot multiply an unbounded MemoryRange by 0' if !bounded? && other == 0 - MemoryRange.new(@floor * other, bounded? ? @ceiling * other : nil) - end - - # Compare this memory range for equality with another memory range - # - # @param [MemoryRange] other - # @return [Boolean] the result - def ==(other) - @floor == other.floor && @ceiling == other.ceiling - end - - # Returns a string representation of this range. - # - # @return [String] the string representation of this range - def to_s - "#{@floor}..#{@ceiling}" - end - - private - - RANGE_SEPARATOR = '..'.freeze - - private_constant :RANGE_SEPARATOR - - def get_bounds(range) - if range.index(RANGE_SEPARATOR) - lower_bound, upper_bound = range.split(RANGE_SEPARATOR) - lower_bound = '0' if lower_bound.nil? || lower_bound == '' - return lower_bound, upper_bound - else - return range, range - end - end - - def create_memory_size(size) - MemorySize.new(size) - end - - def validate_memory_size(size) - fail "Invalid MemorySize parameter of type #{size.class}" unless size.is_a? MemorySize - end - - end - - end -end diff --git a/lib/java_buildpack/jre/memory/memory_size.rb b/lib/java_buildpack/jre/memory/memory_size.rb deleted file mode 100644 index 75ed8207ba..0000000000 --- a/lib/java_buildpack/jre/memory/memory_size.rb +++ /dev/null @@ -1,166 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/jre' - -module JavaBuildpack - module Jre - - # A class representing the size of a category of memory. - class MemorySize - include Comparable - - # Creates a memory size based on a memory size string including a unit of 'K', 'M', or 'G'. - # - # @param [String] size a memory size including a unit - def initialize(size) - if size == '0' - @bytes = 0 - else - fail "Invalid memory size '#{size}'" if !size || size.length < 2 - unit = size[-1] - v = size[0..-2] - fail "Invalid memory size '#{size}'" unless integer? v - v = size.to_i - - store_bytes unit, v, size - end - end - - # Returns a memory size as a string including a unit. If the memory size is not a whole number, it is rounded - # down. The returned unit is always kilobytes, megabytes, or gigabytes which are commonly used units. - # - # @return [String] the memory size as a string, e.g. "10K" - def to_s - kilobytes = (@bytes / KILO).round - if kilobytes == 0 - '0' - elsif kilobytes % KILO == 0 - megabytes = kilobytes / KILO - if megabytes % KILO == 0 - gigabytes = megabytes / KILO - gigabytes.to_s + 'G' - else - megabytes.to_s + 'M' - end - else - kilobytes.to_s + 'K' - end - end - - # Compare this memory size with another memory size - # - # @param [MemorySize, 0] other - # @return [Numeric] the result - def <=>(other) - if other == 0 - @bytes <=> 0 - else - fail "Cannot compare a MemorySize to an instance of #{other.class}" unless other.is_a? MemorySize - @bytes <=> other.bytes - end - end - - # Add a memory size to this memory size. - # - # @param [MemorySize] other the memory size to add - # @return [MemorySize] the result - def +(other) - memory_size_operation(other) do |self_bytes, other_bytes| - self_bytes + other_bytes - end - end - - # Multiply this memory size by a numeric factor. - # - # @param [Numeric] other the factor to multiply by - # @return [MemorySize] the result - def *(other) - fail "Cannot multiply a Memory size by an instance of #{other.class}" unless other.is_a? Numeric - from_numeric((@bytes * other).round) - end - - # Subtract a memory size from this memory size. - # - # @param [MemorySize] other the memory size to subtract - # @return [MemorySize] the result - def -(other) - memory_size_operation(other) do |self_bytes, other_bytes| - self_bytes - other_bytes - end - end - - # Divide a memory size by a memory size or a numeric value. The units are respected, so the result of diving by a - # memory size is a numeric whereas the result of dividing by a numeric value is a memory size. - # - # @param [MemorySize, Numeric] other the memory size or numeric value to divide by - # @return [MemorySize, Numeric] the result - def /(other) - return @bytes / other.bytes.to_f if other.is_a? MemorySize - return from_numeric((@bytes / other.to_f).round) if other.is_a? Numeric - fail "Cannot divide a MemorySize by an instance of #{other.class}" - end - - # @!attribute [r] bytes - # @return [Numeric] the size in bytes of this memory size - attr_reader :bytes - - protected :bytes - - private - - KILO = 1024.freeze - - private_constant :KILO - - def store_bytes(unit, v, size) - # Store the number of bytes. - case unit - when 'b', 'B' - @bytes = v - when 'k', 'K' - @bytes = v * KILO - when 'm', 'M' - @bytes = KILO * KILO * v - when 'g', 'G' - @bytes = KILO * KILO * KILO * v - else - fail "Invalid unit '#{unit}' in memory size '#{size}'" - end - end - - def memory_size_operation(other) - fail "Invalid parameter: instance of #{other.class} is not a MemorySize" unless other.is_a? MemorySize - from_numeric(yield @bytes, other.bytes) - end - - def integer?(v) - f = Float(v) - f && f.floor == f - rescue - false - end - - def from_numeric(n) - MemorySize.new("#{n}B") - end - - # Zero byte memory size - ZERO = MemorySize.new('0B').freeze - end - - end -end diff --git a/lib/java_buildpack/jre/memory/openjdk_memory_heuristic_factory.rb b/lib/java_buildpack/jre/memory/openjdk_memory_heuristic_factory.rb deleted file mode 100644 index e36017a734..0000000000 --- a/lib/java_buildpack/jre/memory/openjdk_memory_heuristic_factory.rb +++ /dev/null @@ -1,64 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/jre' -require 'java_buildpack/jre/memory/weight_balancing_memory_heuristic' -require 'java_buildpack/util/tokenized_version' - -module JavaBuildpack - module Jre - - # A MemoryBucket is used to calculate default sizes for various type of memory - class OpenJDKMemoryHeuristicFactory - - private_class_method :new - - class << self - - # Returns a memory heuristics instance for the given version of OpenJDK. - # - # @param [Hash] sizes any sizes specified by the user - # @param [Hash] heuristics the memory heuristics specified by the user - # @param [JavaBuildpack::Util::TokenizedVersion] version the version of OpenJDK - # @return [WeightBalancingMemoryHeuristic] the memory heuristics instance - def create_memory_heuristic(sizes, heuristics, version) - extra = permgen_or_metaspace(version) - WeightBalancingMemoryHeuristic.new(sizes, heuristics, VALID_TYPES.dup << extra, JAVA_OPTS) - end - - private - - VALID_TYPES = %w(heap stack native).freeze - - private_constant :VALID_TYPES - - JAVA_OPTS = { - 'heap' => ->(v) { %W(-Xmx#{v} -Xms#{v}) }, - 'metaspace' => ->(v) { %W(-XX:MaxMetaspaceSize=#{v} -XX:MetaspaceSize=#{v}) }, - 'permgen' => ->(v) { %W(-XX:MaxPermSize=#{v} -XX:PermSize=#{v}) }, - 'stack' => ->(v) { ["-Xss#{v}"] } - }.freeze - - def permgen_or_metaspace(version) - version < JavaBuildpack::Util::TokenizedVersion.new('1.8.0') ? 'permgen' : 'metaspace' - end - - end - - end - - end -end diff --git a/lib/java_buildpack/jre/memory/stack_memory_bucket.rb b/lib/java_buildpack/jre/memory/stack_memory_bucket.rb deleted file mode 100644 index f6bf8fd148..0000000000 --- a/lib/java_buildpack/jre/memory/stack_memory_bucket.rb +++ /dev/null @@ -1,53 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/jre' -require 'java_buildpack/jre/memory/memory_bucket' -require 'java_buildpack/jre/memory/memory_size' - -module JavaBuildpack - module Jre - - # This class represents a memory bucket for stack memory. This is treated differently to other memory buckets - # which have absolute sizes since stack memory is specified in terms of the size of an individual stack with no - # definition of how many stacks may exist. - class StackMemoryBucket < MemoryBucket - - # Constructs a stack memory bucket. - # - # @param [Numeric] weighting a number between 0 and 1 corresponding to the proportion of total memory which this - # memory bucket should consume by default - # @param [MemoryRange, nil] range a user-specified range for the memory bucket or nil if the user did not specify - # a range - def initialize(weighting, range) - super('stack', weighting, range) - end - - # Returns the default stack size. - # - # @return [MemorySize] the default stack size - def default_size - range.floor == 0 ? JVM_DEFAULT_STACK_SIZE : range.floor - end - - JVM_DEFAULT_STACK_SIZE = MemorySize.new('1M').freeze - - private_constant :JVM_DEFAULT_STACK_SIZE - - end - - end -end diff --git a/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb b/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb deleted file mode 100644 index 46abf6cce5..0000000000 --- a/lib/java_buildpack/jre/memory/weight_balancing_memory_heuristic.rb +++ /dev/null @@ -1,245 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/logging/logger_factory' -require 'java_buildpack/jre' -require 'java_buildpack/jre/memory/memory_limit' -require 'java_buildpack/jre/memory/memory_range' -require 'java_buildpack/jre/memory/memory_size' -require 'java_buildpack/jre/memory/memory_bucket' -require 'java_buildpack/jre/memory/stack_memory_bucket' - -module JavaBuildpack - module Jre - - # A utility for defaulting Java memory settings. - class WeightBalancingMemoryHeuristic - - # Creates an instance based on a hash containing memory settings, and the application's memory size in - # $MEMORY_LIMIT. - # - # @param [Hash] sizes any sizes specified by the user - # @param [Hash] heuristics the memory heuristics specified by the user - # @param [Array] valid_types the valid types of memory - # @param [Hash] java_opts a mapping from a memory type to a +JAVA_OPTS+ option - def initialize(sizes, heuristics, valid_types, java_opts) - @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger WeightBalancingMemoryHeuristic - validate 'size', valid_types, sizes.keys - validate 'heuristic', valid_types, heuristics.keys - @memory_limit = MemoryLimit.memory_limit - @sizes = sizes - @heuristics = heuristics - @java_opts = java_opts - end - - # Computes the JRE memory switch values based on the current state. - # - # @return [Array] an array of JRE memory switches with values - def resolve - buckets = create_memory_buckets(@sizes, @heuristics) - - if @memory_limit - allocate_by_balancing(buckets) - else - allocate_lower_bounds(buckets) - end - - switches(buckets) - end - - private - - NATIVE_MEMORY_WARNING_FACTOR = 3.freeze - - TOTAL_MEMORY_WARNING_FACTOR = 0.8.freeze - - CLOSE_TO_DEFAULT_FACTOR = 0.1.freeze - - private_constant :NATIVE_MEMORY_WARNING_FACTOR, :TOTAL_MEMORY_WARNING_FACTOR, :CLOSE_TO_DEFAULT_FACTOR - - def allocate_lower_bounds(buckets) - buckets.each_value do |bucket| - bucket.size = bucket.range.floor - end - end - - def weighted_proportion(bucket, buckets) - apply_weighting_to_memory_limit(bucket, calculate_total_weighting(buckets)) - end - - def apply_weighting_to_memory_limit(bucket, total_weighting) - apply_weighting(@memory_limit, bucket, total_weighting) - end - - def apply_weighting(memory, bucket, total_weighting) - (memory * bucket.weighting) / total_weighting - end - - def allocate_by_balancing(buckets) - stack_bucket = buckets['stack'] - if stack_bucket - # Convert stack range from range of stack sizes to range of total stack memory - buckets['stack'], num_threads = normalise_stack_bucket(stack_bucket, buckets) - end - - balance_buckets(buckets) - - issue_memory_wastage_warning(buckets) - issue_close_to_default_warnings(buckets) - - return unless stack_bucket - - # Convert stack size from total stack memory to stack size - stack_bucket.size = buckets['stack'].size / num_threads - buckets['stack'] = stack_bucket - end - - def normalise_stack_bucket(stack_bucket, buckets) - stack_memory = weighted_proportion(stack_bucket, buckets) - num_threads = [stack_memory / stack_bucket.default_size, 1].max - normalised_bucket = MemoryBucket.new('normalised stack', stack_bucket.weighting, - stack_bucket.range * num_threads) - [normalised_bucket, num_threads] - end - - def balance_buckets(buckets) - remaining_buckets = buckets.clone - remaining_memory = @memory_limit - deleted = true - while !remaining_buckets.empty? && deleted - remaining_memory, deleted = balance_remainder(remaining_buckets, remaining_memory) - end - end - - def balance_remainder(remaining_buckets, remaining_memory) - deleted = false - total_weighting = calculate_total_weighting remaining_buckets - - allocated_memory = MemorySize::ZERO - remaining_buckets.each do |type, bucket| - size = apply_weighting(remaining_memory, bucket, total_weighting) - if bucket.range.contains? size - bucket.size = size - else - allocated_memory = constrain_bucket_size(allocated_memory, bucket, size) - remaining_buckets.delete type - deleted = true - end - end - remaining_memory -= allocated_memory - fail "Total memory #{@memory_limit} exceeded by configured memory #{@sizes}" if remaining_memory < 0 - [remaining_memory, deleted] - end - - def constrain_bucket_size(allocated_memory, bucket, size) - constrained_size = bucket.range.constrain(size) - bucket.size = constrained_size - allocated_memory + constrained_size - end - - def calculate_total_weighting(buckets) - total_weighting = 0 - buckets.each_value do |bucket| - total_weighting += bucket.weighting - end - total_weighting - end - - def create_memory_bucket(type, weighting, range) - if type == 'stack' - StackMemoryBucket.new(weighting, range) - else - MemoryBucket.new(type, weighting, range) - end - end - - def create_memory_buckets(sizes, heuristics) - buckets = {} - - heuristics.each_pair do |type, weighting| - range = nil_safe_range sizes[type] - buckets[type] = create_memory_bucket(type, weighting, range) - end - - buckets - end - - def issue_memory_wastage_warning(buckets) - native_bucket = buckets['native'] - if native_bucket && native_bucket.range.floor == 0 - if native_bucket.size > weighted_proportion(native_bucket, buckets) * NATIVE_MEMORY_WARNING_FACTOR - @logger.warn do - "There is more than #{NATIVE_MEMORY_WARNING_FACTOR} times more spare native memory than the default, " \ - 'so configured Java memory may be too small or available memory may be too large' - end - end - end - - total_size = MemorySize::ZERO - buckets.each_value { |bucket| total_size += bucket.size } - return unless @memory_limit * TOTAL_MEMORY_WARNING_FACTOR > total_size - - @logger.warn do - "The allocated Java memory sizes total #{total_size} which is less than #{TOTAL_MEMORY_WARNING_FACTOR} of " \ - 'the available memory, so configured Java memory sizes may be too small or available memory may be too large' - end - end - - def nil_safe_range(size) - size ? MemoryRange.new(size) : MemoryRange.new('..') - end - - def validate(type, expected, actual) - actual.each do |key| - fail "'#{key}' is not a valid memory #{type}" unless expected.include? key - end - end - - def issue_close_to_default_warnings(buckets) - total_weighting = calculate_total_weighting buckets - buckets.each do |type, bucket| - check_close_to_default(type, bucket, total_weighting) if type != 'stack' && @sizes[type] - end - end - - def check_close_to_default(type, bucket, total_weighting) - return unless bucket.range.degenerate? - - default_size = apply_weighting_to_memory_limit(bucket, total_weighting) - actual_size = bucket.size - if default_size > 0 - factor = ((actual_size - default_size) / default_size).abs - @logger.debug { "factor for memory size #{type} is #{factor}" } - end - - return unless (default_size == 0 && actual_size == 0) || (factor && (factor < CLOSE_TO_DEFAULT_FACTOR)) - - @logger.warn do - "The computed value #{actual_size} of memory size #{type} is close to the default value #{default_size}. " \ - 'Consider taking the default.' - end - end - - def switches(buckets) - buckets.flat_map do |type, bucket| - @java_opts[type][bucket.size] if bucket.size && bucket.size > 0 && @java_opts.key?(type) - end.compact - end - - end - - end -end diff --git a/lib/java_buildpack/jre/open_jdk_like.rb b/lib/java_buildpack/jre/open_jdk_like.rb index ebb624832e..88badc369d 100644 --- a/lib/java_buildpack/jre/open_jdk_like.rb +++ b/lib/java_buildpack/jre/open_jdk_like.rb @@ -14,79 +14,36 @@ # See the License for the specific language governing permissions and # limitations under the License. -require 'fileutils' -require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/component/modular_component' require 'java_buildpack/jre' -require 'java_buildpack/jre/memory/openjdk_memory_heuristic_factory' -require 'java_buildpack/util/tokenized_version' +require 'java_buildpack/jre/open_jdk_like_jre' +require 'java_buildpack/jre/open_jdk_like_memory_calculator' module JavaBuildpack module Jre # Encapsulates the detect, compile, and release functionality for selecting an OpenJDK-like JRE. - class OpenJDKLike < JavaBuildpack::Component::VersionedDependencyComponent + class OpenJDKLike < JavaBuildpack::Component::ModularComponent - # Creates an instance - # - # @param [Hash] context a collection of utilities used the component - def initialize(context) - @application = context[:application] - @component_name = self.class.to_s.space_case - @configuration = context[:configuration] - @droplet = context[:droplet] + protected - @droplet.java_home.root = @droplet.sandbox + # (see JavaBuildpack::Component::ModularComponent#command) + def command + @sub_components.find { |candidate| candidate.is_a? OpenJDKLikeMemoryCalculator }.memory_calculation_command end - # (see JavaBuildpack::Component::BaseComponent#detect) - def detect - @version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, - @configuration) - @droplet.java_home.version = @version - super + # (see JavaBuildpack::Component::ModularComponent#sub_components) + def sub_components(context) + [ + OpenJDKLikeJre.new(sub_configuration_context(context, 'jre') + .merge(component_name: self.class.to_s.space_case)), + OpenJDKLikeMemoryCalculator.new(sub_configuration_context(context, 'memory_calculator')) + ] end - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_tar - @droplet.copy_resources - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release - @droplet.java_opts - .add_system_property('java.io.tmpdir', '$TMPDIR') - .add_option('-XX:OnOutOfMemoryError', killjava) - .concat memory - end - - private - - KEY_MEMORY_HEURISTICS = 'memory_heuristics'.freeze - - KEY_MEMORY_SIZES = 'memory_sizes'.freeze - - VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0').freeze - - private_constant :KEY_MEMORY_HEURISTICS, :KEY_MEMORY_SIZES, :VERSION_8 - - def killjava - @droplet.sandbox + 'bin/killjava.sh' - end - - def memory - sizes = @configuration[KEY_MEMORY_SIZES] ? @configuration[KEY_MEMORY_SIZES].clone : {} - heuristics = @configuration[KEY_MEMORY_HEURISTICS] ? @configuration[KEY_MEMORY_HEURISTICS].clone : {} - - if @version < VERSION_8 - heuristics.delete 'metaspace' - sizes.delete 'metaspace' - else - heuristics.delete 'permgen' - sizes.delete 'permgen' - end - - OpenJDKMemoryHeuristicFactory.create_memory_heuristic(sizes, heuristics, @version).resolve + # (see JavaBuildpack::Component::ModularComponent#supports?) + def supports? + true end end diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb new file mode 100644 index 0000000000..d2b74013c3 --- /dev/null +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -0,0 +1,70 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/jre' +require 'java_buildpack/util/tokenized_version' + +module JavaBuildpack + module Jre + + # Encapsulates the detect, compile, and release functionality for selecting an OpenJDK-like JRE. + class OpenJDKLikeJre < JavaBuildpack::Component::VersionedDependencyComponent + + # Creates an instance + # + # @param [Hash] context a collection of utilities used the component + def initialize(context) + @application = context[:application] + @component_name = context[:component_name] + @configuration = context[:configuration] + @droplet = context[:droplet] + + @droplet.java_home.root = @droplet.sandbox + end + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + @version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, + @configuration) + @droplet.java_home.version = @version + super + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_tar + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts + .add_system_property('java.io.tmpdir', '$TMPDIR') + .add_option('-XX:OnOutOfMemoryError', killjava) + end + + private + + def killjava + @droplet.sandbox + 'bin/killjava.sh' + end + + end + + end +end diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb new file mode 100644 index 0000000000..17d70b6dee --- /dev/null +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -0,0 +1,108 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/jre' +require 'java_buildpack/util/qualify_path' +require 'open3' + +module JavaBuildpack + module Jre + + # Encapsulates the detect, compile, and release functionality for the OpenJDK-like memory calculator + class OpenJDKLikeMemoryCalculator < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download(@version, @uri) do |file| + FileUtils.mkdir_p memory_calculator.parent + FileUtils.cp_r(file.path, memory_calculator) + memory_calculator.chmod 0755 + end + + shell "#{qualify_path memory_calculator, Pathname.new(Dir.pwd)} -memorySizes=#{memory_sizes @configuration} " \ + "-memoryWeights=#{memory_weights @configuration} -totMemory=$MEMORY_LIMIT" + end + + # Returns a fully qualified memory calculation command to be prepended to the buildpack's command sequence + # + # @return [String] the memory calculation command + def memory_calculation_command + "CALCULATED_MEMORY=$(#{qualify_path memory_calculator, @droplet.root} " \ + "-memorySizes=#{memory_sizes @configuration} -memoryWeights=#{memory_weights @configuration} " \ + '-totMemory=$MEMORY_LIMIT)' + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts.add_preformatted_options '"$CALCULATED_MEMORY"' + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + private + + def memory_calculator + @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{@version}" + end + + def memory_sizes(configuration) + memory_sizes = version_specific configuration['memory_sizes'] + memory_sizes.map { |k, v| "#{k}:#{v}" }.join(',') + end + + def memory_weights(configuration) + memory_sizes = version_specific configuration['memory_heuristics'] + memory_sizes.map { |k, v| "#{k}:#{v}" }.join(',') + end + + def version_specific(configuration) + if @droplet.java_home.java_8_or_later? + configuration.delete 'permgen' + else + configuration.delete 'metaspace' + end + + configuration + end + + def shell(*args) + Open3.popen3(*args) do |_stdin, stdout, stderr, wait_thr| + status = wait_thr.value + stderr_content = stderr.gets nil + stdout_content = stdout.gets nil + + puts " #{stderr_content}" if stderr_content + + if status == 0 + puts " Memory Settings: #{stdout_content}" + else + fail + end + end + end + + end + + end +end diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index fb56c9cd8f..db8d9fd89c 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -60,9 +60,15 @@ def initialize(mutable_cache_root = Pathname.new(Dir.tmpdir), *immutable_cache_r # already in the cache # @return [Void] def get(uri, &block) - cached_file, downloaded = nil, nil + cached_file = nil + downloaded = nil + cached_file, downloaded = from_mutable_cache uri if InternetAvailability.instance.available? - cached_file, downloaded = from_immutable_caches(uri), false unless cached_file + + unless cached_file + cached_file = from_immutable_caches(uri) + downloaded = false + end fail "Unable to find cached file for #{uri.sanitize_uri}" unless cached_file cached_file.cached(File::RDONLY | File::BINARY, downloaded, &block) @@ -288,7 +294,7 @@ def attempt_update(cached_file, http, uri) end def validate_size(expected_size, cached_file) - return unless expected_size + return unless expected_size actual_size = cached_file.cached(File::RDONLY) { |f| f.size } @logger.debug { "Validated content size #{actual_size} is #{expected_size}" } diff --git a/lib/java_buildpack/util/cache/internet_availability.rb b/lib/java_buildpack/util/cache/internet_availability.rb index a0608c2c58..60b563e775 100644 --- a/lib/java_buildpack/util/cache/internet_availability.rb +++ b/lib/java_buildpack/util/cache/internet_availability.rb @@ -47,7 +47,7 @@ def available? # # @param [Boolean] available whether the internet is available # @param [String, nil] message an optional message to be printed when the availability is set - # @yields an environment with internet availability temporarily overridden if block given + # @yield an environment with internet availability temporarily overridden if block given def available(available, message = nil) @monitor.synchronize do if block_given? diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index de8b325817..5b090a5439 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -84,7 +84,8 @@ def char_compare(c1, c2) def major_or_minor_and_tail(s) if s.nil? || s.empty? - major_or_minor, tail = nil, nil + major_or_minor = nil + tail = nil else fail "Invalid version '#{s}': must not end in '.'" if s[-1] == '.' fail "Invalid version '#{s}': missing component" if s =~ /\.[\._]/ @@ -100,7 +101,8 @@ def major_or_minor_and_tail(s) def micro_and_qualifier(s) if s.nil? || s.empty? - micro, qualifier = nil, nil + micro = nil + qualifier = nil else fail "Invalid version '#{s}': must not end in '_'" if s[-1] == '_' tokens = s.match(/^([^\_]+)(?:_(.*))?/) diff --git a/spec/application_helper.rb b/spec/application_helper.rb index bf6775f88d..439a968587 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -65,8 +65,12 @@ application end - after do - FileUtils.rm_rf app_dir + after do |example| + if example.metadata[:no_cleanup] + puts "Application Directory: #{app_dir}" + else + FileUtils.rm_rf app_dir + end end end diff --git a/spec/fixtures/stub-memory-calculator b/spec/fixtures/stub-memory-calculator new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index e768cf46b5..071460cc5c 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -38,8 +38,12 @@ FileUtils.cp_r "spec/fixtures/#{buildpack_fixture.chomp}/.", buildpack_dir if buildpack_fixture end - after do - FileUtils.rm_rf buildpack_dir + after do |example| + if example.metadata[:no_cleanup] + puts "Buildpack Directory: #{buildpack_dir}" + else + FileUtils.rm_rf buildpack_dir + end end def run(command) diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index fde998b336..5c3a95a44a 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -16,10 +16,16 @@ require 'spec_helper' require 'java_buildpack/component/immutable_java_home' +require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Component::ImmutableJavaHome do - let(:delegate) { double('delegate', root: Pathname.new('test-java-home'), version: %w(1 2 3 u04)) } + let(:delegate) do + double('delegate', + root: Pathname.new('test-java-home'), + java_8_or_later?: true, + version: JavaBuildpack::Util::TokenizedVersion.new('1.2.3_u04')) + end let(:immutable_java_home) { described_class.new delegate, Pathname.new('.') } @@ -35,4 +41,8 @@ expect(immutable_java_home.version).to eq(%w(1 2 3 u04)) end + it 'returns the delegate Java 8 or later' do + expect(immutable_java_home.java_8_or_later?).to be + end + end diff --git a/spec/java_buildpack/component/mutable_java_home_spec.rb b/spec/java_buildpack/component/mutable_java_home_spec.rb index bf47a99110..7c694f4eb2 100644 --- a/spec/java_buildpack/component/mutable_java_home_spec.rb +++ b/spec/java_buildpack/component/mutable_java_home_spec.rb @@ -16,13 +16,14 @@ require 'spec_helper' require 'java_buildpack/component/mutable_java_home' +require 'java_buildpack/util/tokenized_version' require 'pathname' describe JavaBuildpack::Component::MutableJavaHome do let(:path) { Pathname.new('foo/bar') } - let(:java_version) { %w(1 2 3 u04) } + let(:java_version) { JavaBuildpack::Util::TokenizedVersion.new('1.2.3_u04') } let(:mutable_java_home) { described_class.new } @@ -36,4 +37,24 @@ expect(mutable_java_home.version).to eq(java_version) end + it 'recognizes Java 6' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.6.0') + expect(mutable_java_home.java_8_or_later?).not_to be + end + + it 'recognizes Java 7' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0') + expect(mutable_java_home.java_8_or_later?).not_to be + end + + it 'recognizes Java 8' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0') + expect(mutable_java_home.java_8_or_later?).to be + end + + it 'recognizes Java 9' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.9.0') + expect(mutable_java_home.java_8_or_later?).to be + end + end diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index 7832dd8ec5..bb6dd218a0 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -83,7 +83,6 @@ end it 'returns command' do - expect(component.command).to eq("#{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 test-opt-1 -Dhttp.port=$PORT\" " \ '$PWD/.java-buildpack/tomcat/bin/catalina.sh run') end diff --git a/spec/java_buildpack/framework/new_relic_agent_spec.rb b/spec/java_buildpack/framework/new_relic_agent_spec.rb index 355dd8045d..5d188eb0d1 100644 --- a/spec/java_buildpack/framework/new_relic_agent_spec.rb +++ b/spec/java_buildpack/framework/new_relic_agent_spec.rb @@ -17,6 +17,7 @@ require 'spec_helper' require 'component_helper' require 'java_buildpack/framework/new_relic_agent' +require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Framework::NewRelicAgent do include_context 'component_helper' @@ -53,6 +54,7 @@ it 'updates JAVA_OPTS' do allow(services).to receive(:find_service).and_return('credentials' => { 'licenseKey' => 'test-license-key' }) + allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.7.0_u10')) component.release @@ -65,7 +67,7 @@ it 'updates JAVA_OPTS on Java 8' do allow(services).to receive(:find_service).and_return('credentials' => { 'licenseKey' => 'test-license-key' }) - allow(java_home).to receive(:version).and_return(%w(1 8 0 u10)) + allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.8.0_u10')) component.release diff --git a/spec/java_buildpack/jre/memory/memory_bucket_spec.rb b/spec/java_buildpack/jre/memory/memory_bucket_spec.rb deleted file mode 100644 index 764fb980c7..0000000000 --- a/spec/java_buildpack/jre/memory/memory_bucket_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'logging_helper' -require 'java_buildpack/jre/memory/memory_bucket' -require 'java_buildpack/jre/memory/memory_range' -require 'java_buildpack/jre/memory/memory_size' - -describe JavaBuildpack::Jre::MemoryBucket do - include_context 'logging_helper' - - let(:test_name) { 'bucket-name' } - let(:test_weighting) { 0.5 } - let(:test_range) { JavaBuildpack::Jre::MemoryRange.new('10M..10M') } - - it 'fails to construct if name is nil' do - expect { described_class.new(nil, test_weighting, test_range) }.to raise_error(/Invalid MemoryBucket name/) - end - - it 'fails to construct if name is the empty string' do - expect { described_class.new('', test_weighting, test_range) }.to raise_error(/Invalid MemoryBucket name/) - end - - it 'fails to construct if weighting is nil' do - expect { described_class.new(test_name, nil, test_range) }.to raise_error(/Invalid weighting/) - end - - it 'fails to construct if weighting is not numeric' do - expect { described_class.new(test_name, 'x', test_range) }.to raise_error(/Invalid weighting/) - end - - it 'fails to construct if weighting is negative' do - expect { described_class.new(test_name, -0.1, test_range) }.to raise_error(/Invalid weighting/) - end - - it 'initializes size to nil' do - memory_bucket = described_class.new(test_name, test_weighting, test_range) - expect(memory_bucket.size).to eq(nil) - end - - it 'fails to construct if range is invalid' do - expect { described_class.new(test_name, test_weighting, 'x') }.to raise_error(/Invalid\ 'range'\ parameter/) - end - -end diff --git a/spec/java_buildpack/jre/memory/memory_limit_spec.rb b/spec/java_buildpack/jre/memory/memory_limit_spec.rb deleted file mode 100644 index 3989194121..0000000000 --- a/spec/java_buildpack/jre/memory/memory_limit_spec.rb +++ /dev/null @@ -1,79 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'memory_limit_helper' -require 'java_buildpack/jre/memory/memory_limit' -require 'java_buildpack/jre/memory/memory_size' - -describe JavaBuildpack::Jre::MemoryLimit do - include_context 'memory_limit_helper' - - it 'accepts memory with an uppercase G', - memory_limit: '1G' do - - expect(described_class.memory_limit).to eq(JavaBuildpack::Jre::MemorySize.new('1048576K')) - end - - it 'accepts memory with an lowercase G', - memory_limit: '1g' do - - expect(described_class.memory_limit).to eq(JavaBuildpack::Jre::MemorySize.new('1048576K')) - end - - it 'accepts memory with an uppercase M', - memory_limit: '1M' do - - expect(described_class.memory_limit).to eq(JavaBuildpack::Jre::MemorySize.new('1024K')) - end - - it 'accepts memory with an lowercase M', - memory_limit: '1m' do - - expect(described_class.memory_limit).to eq(JavaBuildpack::Jre::MemorySize.new('1024K')) - end - - it 'returns nil if a memory limit is not specified', - memory_limit: nil do - - expect(described_class.memory_limit).to be_nil - end - - it 'fails if a memory limit does not have a unit', - memory_limit: '-1' do - - expect { described_class.memory_limit }.to raise_error(/Invalid/) - end - - it 'fails if a memory limit is not an number', - memory_limit: 'xm' do - - expect { described_class.memory_limit }.to raise_error(/Invalid/) - end - - it 'fails if a memory limit is not an integer', - memory_limit: '-1.1m' do - - expect { described_class.memory_limit }.to raise_error(/Invalid/) - end - - it 'fails if a memory limit is negative', - memory_limit: '-1m' do - - expect { described_class.memory_limit }.to raise_error(/Invalid/) - end - -end diff --git a/spec/java_buildpack/jre/memory/memory_range_spec.rb b/spec/java_buildpack/jre/memory/memory_range_spec.rb deleted file mode 100644 index 70a22a54a4..0000000000 --- a/spec/java_buildpack/jre/memory/memory_range_spec.rb +++ /dev/null @@ -1,161 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'java_buildpack/jre/memory/memory_range' -require 'java_buildpack/jre/memory/memory_size' - -describe JavaBuildpack::Jre::MemoryRange do - - let(:low) { JavaBuildpack::Jre::MemorySize.new('1m') } - - let(:mid) { JavaBuildpack::Jre::MemorySize.new('4m') } - - let(:test_lower_bound) { JavaBuildpack::Jre::MemorySize.new('3m') } - - let(:test_upper_bound) { JavaBuildpack::Jre::MemorySize.new('5m') } - - it 'accepts an absolute memory size and produce the corresponding tight range' do - range = described_class.new('3m') - expect(range.floor).to eq(test_lower_bound) - expect(range.ceiling).to eq(test_lower_bound) - end - - it 'accepts a range with specified lower and upper bounds' do - range = described_class.new('3m..5m') - expect(range.floor).to eq(test_lower_bound) - expect(range.ceiling).to eq(test_upper_bound) - end - - it 'accepts a range with specified lower bound, but no upper bound' do - range = described_class.new('3m..') - expect(range.floor).to eq(test_lower_bound) - expect(range.bounded?).not_to be - expect(range.ceiling).to be_nil - end - - it 'accepts a range with specified upper bound, but no lower bound' do - range = described_class.new('..5m') - expect(range.floor).to eq(0) - expect(range.ceiling).to eq(test_upper_bound) - end - - it 'accepts a range with no lower or upper bounds' do - range = described_class.new('..') - expect(range.floor).to eq(0) - expect(range.bounded?).not_to be - expect(range.ceiling).to be_nil - end - - it 'detects a memory size lower than a range to lie outside the range' do - range = described_class.new('3m..5m') - expect(range.contains?(0)).to eq(false) - end - - it 'detects a memory size higher than a range to lie outside the range' do - range = described_class.new('3m..5m') - expect(range.contains?(test_upper_bound * 2)).to eq(false) - end - - it 'detects a memory size within a range as lying inside the range' do - range = described_class.new('3m..5m') - expect(range.contains?(mid)).to eq(true) - end - - it 'constrains a memory size lower than a range to the lower bound of the range' do - range = described_class.new('3m..5m') - expect(range.constrain(low)).to eq(test_lower_bound) - end - - it 'constrains a memory size higher than a range to the upper bound of the range' do - range = described_class.new('3m..5m') - expect(range.constrain(test_upper_bound * 2)).to eq(test_upper_bound) - end - - it 'constrains a memory size within the range to be the memory size itself' do - range = described_class.new('3m..5m') - expect(range.constrain(mid)).to eq(mid) - end - - it 'detects a degenerate range' do - range = described_class.new('3m..3m') - expect(range.degenerate?).to eq(true) - end - - it 'detects a non-degenerate range' do - range = described_class.new('3m..5m') - expect(range.degenerate?).to eq(false) - end - - it 'fails if the range string is empty' do - expect { described_class.new('2m..1m') }.to raise_error(/Invalid range/) - end - - it 'fails if the range is empty' do - expect { described_class.new(test_upper_bound, test_lower_bound) }.to raise_error(/Invalid range/) - end - - it 'fails if the lower bound is not a MemorySize' do - expect { described_class.new('', test_upper_bound) }.to raise_error(/Invalid combination of parameter types/) - end - - it 'fails if the upper bound is not a MemorySize' do - expect { described_class.new(test_lower_bound, '') }.to raise_error(/Invalid MemorySize parameter of type/) - end - - it 'accepts valid lower and upper bounds' do - range = described_class.new(test_lower_bound, test_upper_bound) - expect(range.floor).to eq(test_lower_bound) - expect(range.ceiling).to eq(test_upper_bound) - expect(range.bounded?).to be - end - - it 'accepts a lower bound and no upper bound' do - range = described_class.new(test_lower_bound) - expect(range.floor).to eq(test_lower_bound) - expect(range.ceiling).to be_nil - expect(range.bounded?).not_to be - end - - it 'detects a degenerate range constructed from MemorySizes' do - range = described_class.new(test_lower_bound, test_lower_bound) - expect(range.degenerate?).to eq(true) - end - - it 'detects a non-degenerate range constructed from MemorySizes' do - range = described_class.new(test_lower_bound, test_upper_bound) - expect(range.degenerate?).to eq(false) - end - - it 'produces a string representation' do - range = described_class.new('3m..5m') - expect(range.to_s).to eq('3M..5M') - end - - it 'supports multiplication by a numeric' do - range = described_class.new('3m..5m') - expect(range * 2).to eq(described_class.new('6m..10m')) - end - - it 'compares bounded ranges for equality' do - expect(described_class.new('3m..5m')).to eq(described_class.new(test_lower_bound, test_upper_bound)) - end - - it 'compares unbounded ranges for equality' do - expect(described_class.new('3m..')).to eq(described_class.new(test_lower_bound)) - end - -end diff --git a/spec/java_buildpack/jre/memory/memory_size_spec.rb b/spec/java_buildpack/jre/memory/memory_size_spec.rb deleted file mode 100644 index 3c27226463..0000000000 --- a/spec/java_buildpack/jre/memory/memory_size_spec.rb +++ /dev/null @@ -1,138 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'java_buildpack/jre/memory/memory_size' - -describe JavaBuildpack::Jre::MemorySize do - - let(:half_meg) { described_class.new('512K') } - - let(:one_meg) { described_class.new('1M') } - - it 'accepts a memory size in bytes, kilobytes, megabytes, or gigabytes' do - expect(described_class.new('1024B')).to eq(described_class.new('1k')) - expect(described_class.new('1024b')).to eq(described_class.new('1k')) - expect(described_class.new('1M')).to eq(described_class.new('1024k')) - expect(described_class.new('1m')).to eq(described_class.new('1024k')) - expect(described_class.new('1G')).to eq(described_class.new('1048576k')) - expect(described_class.new('1g')).to eq(described_class.new('1048576k')) - end - - it 'fails if nil is passed to the constructor' do - expect { described_class.new(nil) }.to raise_error(/Invalid/) - end - - it 'accepts a zero memory size with no unit' do - expect(described_class.new('0')).to eq(described_class.new('0k')) - end - - it 'fails if a non-zero memory size does not have a unit' do - expect { described_class.new('1') }.to raise_error(/Invalid/) - end - - it 'fails if a memory size has an invalid unit' do - expect { described_class.new('1A') }.to raise_error(/Invalid/) - end - - it 'fails if a memory size is not an number' do - expect { described_class.new('xm') }.to raise_error(/Invalid/) - end - - it 'fails if a memory size is not an integer' do - expect { described_class.new('1.1m') }.to raise_error(/Invalid/) - end - - it 'fails if a memory size has embedded whitespace' do - expect { described_class.new('1 1m') }.to raise_error(/Invalid/) - end - - it 'accepts a negative value' do - expect(described_class.new('-1M')).to eq(described_class.new('-1024k')) - end - - it 'compares values' do - expect(one_meg).to be < described_class.new('1025K') - expect(described_class.new('1025K')).to be > one_meg - end - - it 'compares a described_class to 0' do - expect(one_meg).to be > 0 - end - - it 'fails when a memory size is compared to a non-zero numeric' do - expect { described_class.new('1B') < 2 }.to raise_error(/Cannot compare/) - end - - it 'multiplies values' do - expect(one_meg * 2).to eq(described_class.new('2M')) - end - - it 'fails when a memory size is multiplied by a memory size' do - expect { one_meg * one_meg }.to raise_error(/Cannot multiply/) - end - - it 'subtracts memory values' do - expect(one_meg - half_meg).to eq(half_meg) - end - - it 'fails when a numeric is subtracted from a memory size' do - expect { one_meg - 1 }.to raise_error(/Invalid parameter: instance of Fixnum is not a MemorySize/) - end - - it 'adds memory values' do - expect(half_meg + half_meg).to eq(one_meg) - end - - it 'fails when a numeric is added to a memory size' do - expect { one_meg + 1 }.to raise_error(/Invalid parameter: instance of Fixnum is not a MemorySize/) - end - - it 'divides a memory size by a numeric' do - expect(one_meg / 2).to eq(half_meg) - end - - it 'divides a memory size by a numeric using floating point' do - expect(described_class.new('3B') / 2).to eq(described_class.new('2B')) - end - - it 'divides a memory size by another memory size' do - expect(one_meg / half_meg).to eq(2) - end - - it 'divides a memory size by another memory size using floating point' do - expect(half_meg / one_meg).to eq(0.5) - end - - it 'fails when a memory size is divided by an incorrect type' do - expect { described_class.new('1B') / '' }.to raise_error(/Cannot divide/) - end - - it 'provides a zero memory size' do - expect(described_class::ZERO).to eq(described_class.new('0B')) - end - - it 'converts the memory size to a string' do - expect(described_class::ZERO.to_s).to eq('0') - expect(described_class.new('1K').to_s).to eq('1K') - expect(described_class.new('1k').to_s).to eq('1K') - expect(described_class.new('1M').to_s).to eq('1M') - expect(described_class.new('1m').to_s).to eq('1M') - expect(described_class.new('1G').to_s).to eq('1G') - expect(described_class.new('1g').to_s).to eq('1G') - end - -end diff --git a/spec/java_buildpack/jre/memory/openjdk_memory_heuristic_factory_spec.rb b/spec/java_buildpack/jre/memory/openjdk_memory_heuristic_factory_spec.rb deleted file mode 100644 index 3e7a755121..0000000000 --- a/spec/java_buildpack/jre/memory/openjdk_memory_heuristic_factory_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright (c) 2013 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'java_buildpack/jre/memory/openjdk_memory_heuristic_factory' -require 'java_buildpack/jre/memory/weight_balancing_memory_heuristic' -require 'java_buildpack/util/tokenized_version' -require 'rspec/expectations' - -RSpec::Matchers.define :be_a_hash_like do |expected| - match do |actual| - expected['heap']['1m'] == actual['heap']['1m'] && - expected['metaspace']['2m'] == actual['metaspace']['2m'] && - expected['permgen']['3m'] == actual['permgen']['3m'] && - expected['stack']['4m'] == actual['stack']['4m'] - end -end - -describe JavaBuildpack::Jre::OpenJDKMemoryHeuristicFactory do - - let(:heuristics) { { 'c' => 'd' } } - - let(:post_8) { JavaBuildpack::Util::TokenizedVersion.new('1.8.0') } - - let(:pre_8) { JavaBuildpack::Util::TokenizedVersion.new('1.7.0') } - - let(:sizes) { { 'a' => 'b' } } - - let(:expected_java_memory_options) do - { - 'heap' => ->(v) { %W(-Xmx#{v} -Xms#{v}) }, - 'metaspace' => ->(v) { %W(-XX:MaxMetaspaceSize=#{v} -XX:MetaspaceSize=#{v}) }, - 'permgen' => ->(v) { %W(-XX:MaxPermSize=#{v} -XX:PermSize=#{v}) }, - 'stack' => ->(v) { %W(-Xss#{v}) } - } - end - - it 'passes the appropriate constructor parameters for versions prior to 1.8' do - allow(JavaBuildpack::Jre::WeightBalancingMemoryHeuristic) - .to receive(:new).with(sizes, heuristics, %w(heap stack native permgen), - be_a_hash_like(expected_java_memory_options)) - - described_class.create_memory_heuristic(sizes, heuristics, pre_8) - end - - it 'passes the appropriate constructor parameters for versions 1.8 and higher' do - allow(JavaBuildpack::Jre::WeightBalancingMemoryHeuristic) - .to receive(:new).with(sizes, heuristics, %w(heap stack native metaspace), - be_a_hash_like(expected_java_memory_options)) - - described_class.create_memory_heuristic(sizes, heuristics, post_8) - end - -end diff --git a/spec/java_buildpack/jre/memory/stack_memory_bucket_spec.rb b/spec/java_buildpack/jre/memory/stack_memory_bucket_spec.rb deleted file mode 100644 index 656611399b..0000000000 --- a/spec/java_buildpack/jre/memory/stack_memory_bucket_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'logging_helper' -require 'java_buildpack/jre/memory/stack_memory_bucket' -require 'java_buildpack/jre/memory/memory_bucket' -require 'java_buildpack/jre/memory/memory_range' -require 'java_buildpack/jre/memory/memory_size' - -describe JavaBuildpack::Jre::StackMemoryBucket do - include_context 'logging_helper' - - let(:test_stack_bucket_weighting) { 0.05 } - let(:test_stack_size) { JavaBuildpack::Jre::MemorySize.new('2M') } - let(:test_stack_size_range) { JavaBuildpack::Jre::MemoryRange.new(test_stack_size, test_stack_size) } - - it 'calls the superclass constructor' do - # since we can't easily stub the superclass, test the superclass behaves as expected - stack_memory_bucket = described_class.new(test_stack_bucket_weighting, test_stack_size_range) - expect(stack_memory_bucket.range).to eq(test_stack_size_range) - end - -end diff --git a/spec/java_buildpack/jre/memory/weight_balancing_memory_heuristic_spec.rb b/spec/java_buildpack/jre/memory/weight_balancing_memory_heuristic_spec.rb deleted file mode 100644 index 45ddaca1f5..0000000000 --- a/spec/java_buildpack/jre/memory/weight_balancing_memory_heuristic_spec.rb +++ /dev/null @@ -1,440 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'logging_helper' -require 'memory_limit_helper' -require 'java_buildpack/jre/memory/weight_balancing_memory_heuristic' - -describe JavaBuildpack::Jre::WeightBalancingMemoryHeuristic do - include_context 'logging_helper' - include_context 'memory_limit_helper' - - let(:heuristic) do |example| - sizes = example.metadata[:sizes] || {} - weightings = example.metadata[:weightings] || { 'heap' => 5, 'permgen' => 3, 'stack' => 1, 'native' => 1 } - valid_types = %w(heap permgen stack native) - java_opts = { 'heap' => ->(v) { "-Xmx#{v}" }, 'permgen' => ->(v) { "-XX:MaxPermSize=#{v}" }, - 'stack' => ->(v) { "-Xss#{v}" } } - - described_class.new(sizes, weightings, valid_types, java_opts) - end - - it 'fails if a memory limit is negative', - memory_limit: '-1m' do - - expect { heuristic.resolve }.to raise_error(/Invalid/) - end - - it 'fails if the heap weighting is less than 0', - with_memory_limit: '1m', - weightings: { 'heap' => -1 } do - - expect { heuristic.resolve }.to raise_error(/Invalid/) - end - - it 'fails if the permgen weighting is less than 0', - memory_limit: '1m', - weightings: { 'permgen' => -1 } do - - expect { heuristic.resolve }.to raise_error(/Invalid/) - end - - it 'fails if the stack weighting is less than 0', - memory_limit: '1m', - weightings: { 'stack' => -1 } do - - expect { heuristic.resolve }.to raise_error(/Invalid/) - end - - it 'fails if the native weighting is less than 0', - memory_limit: '1m', - weightings: { 'native' => -1 } do - - expect { heuristic.resolve }.to raise_error(/Invalid/) - end - - it 'fails if a configured weighting is invalid', - memory_limit: '1m', - weightings: { 'native' => 'x' } do - - expect { heuristic.resolve }.to raise_error(/Invalid/) - end - - it 'defaults maximum heap size and permgen size according to the configured weightings', - memory_limit: '1024m' do - - output = heuristic.resolve - - expect(output).to include('-Xmx512M') - expect(output).to include('-XX:MaxPermSize=314572K') - end - - it 'defaults the stack size even with a small memory limit', - memory_limit: '10m' do - - output = heuristic.resolve - - expect(output).to include('-Xss1M') - end - - it 'defaults permgen size according to the configured weightings when maximum heap size is specified', - memory_limit: '4096m', - sizes: { 'stack' => '1m', 'heap' => "#{(4096 * 3 / 4).to_i}m" } do - - output = heuristic.resolve - - expect(output).to include('-Xmx3G') - expect(output).to include('-XX:MaxPermSize=471859K') - end - - it 'defaults maximum heap size according to the configured weightings when maximum permgen size is specified', - memory_limit: '4096m', - sizes: { 'stack' => '1m', 'permgen' => '2g' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=2G') - expect(output).to include('-Xmx1398101K') - end - - it 'defaults maximum heap size and permgen size according to the configured weightings when thread stack size is ' \ - 'specified', - memory_limit: '4096m', - sizes: { 'stack' => '2m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx2G') - expect(output).to include('-XX:MaxPermSize=1258291K') - end - - it 'defaults maximum heap size and permgen size according to the configured weightings when thread stack size is ' \ - 'specified as a range', - memory_limit: '4096m', - sizes: { 'stack' => '2m..3m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx2G') - expect(output).to include('-XX:MaxPermSize=1258291K') - expect(output).to include('-Xss2M') - end - - it 'defaults maximum heap size and permgen size according to the configured weightings when thread stack size is ' \ - 'specified as a range which impinges on heap and permgen', - memory_limit: '4096m', - sizes: { 'stack' => '1g..2g' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx1747626K') - expect(output).to include('-XX:MaxPermSize=1G') - expect(output).to include('-Xss1G') - end - - it 'defaults stack size to the top of its range when heap size and permgen size allow for excess memory', - memory_limit: '4096m', - sizes: { 'heap' => '50m', 'permgen' => '50m', 'stack' => '400m..500m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx50M') - expect(output).to include('-XX:MaxPermSize=50M') - expect(output).to include('-Xss500M') - end - - it 'defaults stack size strictly within its range when heap size and permgen size allow for just enough excess ' \ - 'memory', - memory_limit: '4096m', - sizes: { 'heap' => '3000m', 'permgen' => '196m', 'stack' => '400m..500m' } do - - output = heuristic.resolve - - expect(output).to include('-Xss450000K') - end - - it 'does not apply any defaults when maximum heap size, maximum permgen size, and thread stack size are specified', - memory_limit: '4096m', - sizes: { 'heap' => '1m', 'permgen' => '1m', 'stack' => '2m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx1M') - expect(output).to include('-XX:MaxPermSize=1M') - expect(output).to include('-Xss2M') - end - - it 'works with a single memory type', - memory_limit: '4096m', - weightings: { 'heap' => 5 } do - - output = heuristic.resolve - - expect(output).to include('-Xmx4G') - end - - it 'works with no memory types', - memory_limit: '4096m', - weightings: {} do - - output = heuristic.resolve - - expect(output).to eq([]) - end - - it 'issues a warning when the specified maximum memory sizes imply the total memory size may be too large', - memory_limit: '4096m', - sizes: { 'heap' => '800m', 'permgen' => '800m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx800M') - expect(output).to include('-XX:MaxPermSize=800M') - expect(log_contents).to match(/There is more than .* times more spare native memory than the default/) - end - - it 'issues a warning when the specified maximum memory sizes, including native, imply the total memory size may be ' \ - 'too large', - memory_limit: '4096m', - sizes: { 'heap' => '1m', 'permgen' => '1m', 'stack' => '2m', 'native' => '2000m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx1M') - expect(output).to include('-XX:MaxPermSize=1M') - expect(output).to include('-Xss2M') - expect(log_contents).to match(/allocated Java memory sizes total .* which is less than/) - end - - it 'allows native memory to be fixed', - memory_limit: '4096m', - sizes: { 'permgen' => '1m', 'stack' => '2m', 'native' => '10m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx3763609K') - expect(output).to include('-XX:MaxPermSize=1M') - expect(output).to include('-Xss2M') - end - - it 'allows native memory to be specified as a range with an upper bound', - memory_limit: '4096m', - sizes: { 'permgen' => '1m', 'stack' => '2m', 'native' => '10m..20m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx3753369K') - expect(output).to include('-XX:MaxPermSize=1M') - expect(output).to include('-Xss2M') - end - - it 'issues a warning when the specified maximum heap size is close to the default', - memory_limit: '4096m', - sizes: { 'heap' => '2049m' } do - - heuristic.resolve - - expect(log_contents).to match(/WARN.*is close to the default/) - end - - it 'issues a warning when the specified maximum permgen size is close to the default', - memory_limit: '4096m', - sizes: { 'permgen' => '1339m' } do - - heuristic.resolve - - expect(log_contents).to match(/WARN.*is close to the default/) - end - - it 'does not issue a warning when the specified maximum permgen size is not close to the default', - memory_limit: '1G', - sizes: { 'permgen' => '128M' } do - - heuristic.resolve - - expect(log_contents).not_to match(/WARN.*is close to the default/) - end - - it 'fails when the specified maximum memory is larger than the total memory size', - memory_limit: '4096m', - sizes: { 'heap' => '5g' } do - - expect { heuristic.resolve }.to raise_error(/exceeded/) - end - - it 'defaults nothing when the total memory size is not available', - with_memory_limit: nil do - - output = heuristic.resolve - - expect(output).to eq([]) - end - - it 'uses the calculated default when this falls within a specified range', - memory_limit: '4096m', - sizes: { 'permgen' => '1g..1250m' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1258291K') - end - - it 'uses the upper bound of a range when the calculated default exceeds the upper bound of the range', - memory_limit: '5120m', - sizes: { 'permgen' => '1g..1250m' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1250M') - end - - it 'uses the lower bound of a range when the calculated default is smaller than the lower bound of the range', - memory_limit: '2048m', - sizes: { 'permgen' => '1g..1250m' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1G') - end - - it 'uses the calculated default when this exceeds the lower bound of a specified open range', - memory_limit: '4096m', - sizes: { 'permgen' => '1g..' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1258291K') - end - - it 'uses the lower bound of an open range when the calculated default is smaller than the lower bound of the range', - memory_limit: '2048m', - sizes: { 'permgen' => '1g..' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1G') - end - - it 'uses the calculated default when this falls below the upper bound of an open range', - memory_limit: '4096m', - sizes: { 'permgen' => '..1250m' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1258291K') - end - - it 'uses the upper bound of an open range when the calculated default exceeds the upper bound of the range', - memory_limit: '5120m', - sizes: { 'permgen' => '..1250m' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1250M') - end - - it 'allows open range with no lower or upper bound', - memory_limit: '4096m', - sizes: { 'permgen' => '..' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1258291K') - end - - it 'allows a zero lower bound to be specified without units', - memory_limit: '5120m', - sizes: { 'permgen' => '0..1250m' } do - - output = heuristic.resolve - - expect(output).to include('-XX:MaxPermSize=1250M') - end - - it 'fails if a range is empty', - memory_limit: '4096m', - sizes: { 'permgen' => '2m..1m' } do - - expect { heuristic.resolve }.to raise_error(/Invalid range/) - end - - it 'defaults maximum heap size and permgen size according to the configured weightings and range lower bounds', - memory_limit: '1024m', - sizes: { 'stack' => '1m', 'permgen' => '400m..500m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx445098K') - expect(output).to include('-XX:MaxPermSize=400M') - end - - it 'defaults maximum heap size and permgen size according to the configured weightings and range upper bounds', - memory_limit: '1024m', - sizes: { 'stack' => '1m', 'permgen' => '100m..285m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx543232K') - expect(output).to include('-XX:MaxPermSize=285M') - end - - it 'does not apply any defaults when maximum heap size, maximum permgen size, and thread stack size are specified ' \ - 'as tight ranges', - memory_limit: '4096m', - sizes: { 'heap' => '1m..1024k', 'permgen' => '1024k..1m', 'stack' => '2m..2m' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx1M') - expect(output).to include('-XX:MaxPermSize=1M') - expect(output).to include('-Xss2M') - end - - it 'allows native memory to be specified with no upper bound', - memory_limit: '5120m', - sizes: { 'stack' => '1m..1m', 'native' => '4000m..' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx380M') - expect(output).to include('-XX:MaxPermSize=228M') - expect(output).to include('-Xss1M') - end - - it 'respects lower bounds when there is no memory limit', - memory_limit: nil, - sizes: { 'heap' => '30m..', 'permgen' => '10m', 'stack' => '1m..1m', 'native' => '10m..' } do - - output = heuristic.resolve - - expect(output).to include('-Xmx30M') - expect(output).to include('-XX:MaxPermSize=10M') - expect(output).to include('-Xss1M') - end - - it 'works with other weightings', - memory_limit: '256m', - weightings: { 'heap' => 75, 'permgen' => 10, 'stack' => 5, 'native' => 10 } do - - output = heuristic.resolve - - expect(output).to include('-Xmx192M') - expect(output).to include('-XX:MaxPermSize=26214K') - expect(output).to include('-Xss1M') - end - -end diff --git a/spec/java_buildpack/jre/open_jdk_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_jre_spec.rb deleted file mode 100644 index 111f1b41ba..0000000000 --- a/spec/java_buildpack/jre/open_jdk_jre_spec.rb +++ /dev/null @@ -1,126 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/component/mutable_java_home' -require 'java_buildpack/jre/open_jdk_jre' -require 'java_buildpack/jre/memory/weight_balancing_memory_heuristic' - -describe JavaBuildpack::Jre::OpenJdkJRE do - include_context 'component_helper' - - let(:version_8) { VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } - - let(:version_7) { VERSION_7 = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } - - let(:configuration) do - { 'memory_sizes' => { 'metaspace' => '64m..', - 'permgen' => '64m..' }, - 'memory_heuristics' => { 'heap' => '75', - 'metaspace' => '10', - 'permgen' => '10', - 'stack' => '5', - 'native' => '10' } } - end - - let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } - - let(:memory_heuristic_7) { double('MemoryHeuristic', resolve: %w(opt-7-1 opt-7-2)) } - - let(:memory_heuristic_8) { double('MemoryHeuristic', resolve: %w(opt-8-1 opt-8-2)) } - - before do - allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item).and_return([version_8, 'test-uri']) - allow(JavaBuildpack::Jre::WeightBalancingMemoryHeuristic).to receive(:new).with({ 'permgen' => '64m..' }, - anything, anything, anything) - .and_return(memory_heuristic_7) - allow(JavaBuildpack::Jre::WeightBalancingMemoryHeuristic).to receive(:new).with({ 'metaspace' => '64m..' }, - anything, anything, anything) - .and_return(memory_heuristic_8) - end - - it 'detects with id of openjdk_jre-' do - expect(component.detect).to eq("open-jdk-jre=#{version_8}") - end - - it 'extracts Java from a GZipped TAR', - cache_fixture: 'stub-java.tar.gz' do - - component.detect - component.compile - - expect(sandbox + 'bin/java').to exist - end - - it 'adds the JAVA_HOME to java_home' do - component - - expect(java_home.root).to eq(sandbox) - end - - it 'adds OnOutOfMemoryError to java_opts' do - component.detect - component.release - - expect(java_opts).to include('-XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh') - end - - it 'places the killjava script (with appropriately substituted content) in the diagnostics directory', - cache_fixture: 'stub-java.tar.gz' do - - component.detect - component.compile - - expect(sandbox + 'bin/killjava.sh').to exist - end - - it 'adds java.io.tmpdir to java_opts' do - component.detect - component.release - - expect(java_opts).to include('-Djava.io.tmpdir=$TMPDIR') - end - - it 'removes memory options for a java 8 app', - cache_fixture: 'stub-java.tar.gz' do - - component.detect - component.release - - expect(java_opts).to include('opt-8-1') - expect(java_opts).to include('opt-8-2') - end - - context do - - before do - allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item).and_return([version_7, 'test-uri']) - end - - it 'removes memory options for a java 7 app', - cache_fixture: 'stub-java.tar.gz' do - - component.detect - component.release - - expect(java_opts).to include('opt-7-1') - expect(java_opts).to include('opt-7-2') - end - - end - -end diff --git a/spec/java_buildpack/jre/oracle_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb similarity index 61% rename from spec/java_buildpack/jre/oracle_jre_spec.rb rename to spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index efe333e89f..9294e76f2a 100644 --- a/spec/java_buildpack/jre/oracle_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -17,22 +17,15 @@ require 'spec_helper' require 'component_helper' require 'java_buildpack/component/mutable_java_home' -require 'java_buildpack/jre/oracle_jre' -require 'java_buildpack/jre/memory/weight_balancing_memory_heuristic' +require 'java_buildpack/jre/open_jdk_like_jre' -describe JavaBuildpack::Jre::OracleJRE do +describe JavaBuildpack::Jre::OpenJDKLikeJre do include_context 'component_helper' let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } - let(:memory_heuristic) { double('MemoryHeuristic', resolve: %w(opt-1 opt-2)) } - - before do - allow(JavaBuildpack::Jre::WeightBalancingMemoryHeuristic).to receive(:new).and_return(memory_heuristic) - end - - it 'detects with id of oracle-jre-' do - expect(component.detect).to eq("oracle-jre=#{version}") + it 'detects with id of openjdk_like_jre-' do + expect(component.detect).to eq("open-jdk-like-jre=#{version}") end it 'extracts Java from a GZipped TAR', @@ -50,35 +43,32 @@ expect(java_home.root).to eq(sandbox) end - it 'adds memory options to java_opts' do + it 'adds OnOutOfMemoryError to java_opts' do component.detect component.release - expect(java_opts).to include('opt-1') - expect(java_opts).to include('opt-2') + expect(java_opts).to include('-XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_like_jre/bin/killjava.sh') end - it 'adds OnOutOfMemoryError to java_opts' do + it 'adds java.io.tmpdir to java_opts' do component.detect component.release - expect(java_opts).to include('-XX:OnOutOfMemoryError=$PWD/.java-buildpack/oracle_jre/bin/killjava.sh') + expect(java_opts).to include('-Djava.io.tmpdir=$TMPDIR') end - it 'places the killjava script (with appropriately substituted content) in the diagnostics directory', - cache_fixture: 'stub-java.tar.gz' do + context do - component.detect - component.compile + let(:component_id) { 'open_jdk_jre' } - expect(sandbox + 'bin/killjava.sh').to exist - end + it 'places the killjava script (with appropriately substituted content) in the bin directory', + cache_fixture: 'stub-java.tar.gz' do - it 'adds java.io.tmpdir to java_opts' do - component.detect - component.release + component.detect + component.compile - expect(java_opts).to include('-Djava.io.tmpdir=$TMPDIR') + expect(sandbox + 'bin/killjava.sh').to exist + end end end diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb new file mode 100644 index 0000000000..815bb1477e --- /dev/null +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -0,0 +1,102 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/component/mutable_java_home' +require 'java_buildpack/jre/open_jdk_like_memory_calculator' +require 'java_buildpack/util/qualify_path' + +describe JavaBuildpack::Jre::OpenJDKLikeMemoryCalculator do + include_context 'component_helper' + include JavaBuildpack::Util + + let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } + + let(:version_7) { VERSION_7 = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } + + let(:version_8) { VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } + + let(:configuration) do + { 'memory_sizes' => { 'metaspace' => '64m..', + 'permgen' => '64m..' }, + 'memory_heuristics' => { 'heap' => '75', + 'metaspace' => '10', + 'permgen' => '10', + 'stack' => '5', + 'native' => '10' } } + end + + it 'copies executable to bin directory', + cache_fixture: 'stub-memory-calculator' do + + java_home.version = version_7 + allow(component).to receive(:shell) + + component.compile + + expect(sandbox + "bin/java-buildpack-memory-calculator-#{version}").to exist + end + + it 'chmods executable to 0755', + cache_fixture: 'stub-memory-calculator' do + + java_home.version = version_7 + allow(component).to receive(:shell) + + component.compile + + expect(File.stat(sandbox + "bin/java-buildpack-memory-calculator-#{version}").mode).to eq(0100755) + end + + it 'runs the memory calculator to sanity check', + cache_fixture: 'stub-memory-calculator' do + + java_home.version = version_7 + memory_calculator = qualify_path(sandbox + "bin/java-buildpack-memory-calculator-#{version}", Pathname.new(Dir.pwd)) + + expect(component).to receive(:shell).with("#{memory_calculator} -memorySizes=permgen:64m.. " \ + '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ + '-totMemory=$MEMORY_LIMIT') + + component.compile + end + + it 'create memory calculation command for Java 7' do + java_home.version = version_7 + command = component.memory_calculation_command + + expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ + 'java-buildpack-memory-calculator-0.0.0 -memorySizes=permgen:64m.. ' \ + '-memoryWeights=heap:75,permgen:10,stack:5,native:10 -totMemory=$MEMORY_LIMIT)') + end + + it 'create memory calculation command for Java 8' do + java_home.version = version_8 + command = component.memory_calculation_command + + expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ + 'java-buildpack-memory-calculator-0.0.0 -memorySizes=metaspace:64m.. ' \ + '-memoryWeights=heap:75,metaspace:10,stack:5,native:10 -totMemory=$MEMORY_LIMIT)') + end + + it 'adds $CALCULATED_MEMORY to the JAVA_OPTS' do + component.release + + expect(java_opts).to include('"$CALCULATED_MEMORY"') + end + +end diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb new file mode 100644 index 0000000000..a48ee787d5 --- /dev/null +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -0,0 +1,85 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'fileutils' +require 'java_buildpack/component/mutable_java_home' +require 'java_buildpack/jre/open_jdk_like' +require 'java_buildpack/jre/open_jdk_like_jre' +require 'java_buildpack/jre/open_jdk_like_memory_calculator' + +describe JavaBuildpack::Jre::OpenJDKLike do + include_context 'component_helper' + + let(:component) { StubOpenJDKLike.new context } + + let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } + + let(:version_7) { VERSION_7 = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } + + let(:configuration) do + { 'jre' => jre_configuration, + 'memory_calculator' => memory_calculator_configuration } + end + + let(:jre_configuration) { double('jre_configuration') } + + let(:memory_calculator_configuration) do + { 'memory_sizes' => { 'metaspace' => '64m..', + 'permgen' => '64m..' }, + 'memory_heuristics' => { 'heap' => '75', + 'metaspace' => '10', + 'permgen' => '10', + 'stack' => '5', + 'native' => '10' } } + end + + it 'always supports' do + expect(component.supports?).to be + end + + it 'creates submodules' do + allow_any_instance_of(StubOpenJDKLike).to receive(:supports?).and_return false + + expect(JavaBuildpack::Jre::OpenJDKLikeJre) + .to receive(:new).with(sub_configuration_context(jre_configuration).merge(component_name: 'Stub Open JDK Like')) + expect(JavaBuildpack::Jre::OpenJDKLikeMemoryCalculator) + .to receive(:new).with(sub_configuration_context(memory_calculator_configuration)) + + component.sub_components context + end + + it 'returns command' do + java_home.version = version_7 + expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ + 'java-buildpack-memory-calculator-0.0.0 -memorySizes=permgen:64m.. ' \ + '-memoryWeights=heap:75,permgen:10,stack:5,native:10 -totMemory=$MEMORY_LIMIT)') + end + +end + +class StubOpenJDKLike < JavaBuildpack::Jre::OpenJDKLike + + public :command, :sub_components, :supports? + +end + +def sub_configuration_context(configuration) + c = context.clone + c[:configuration] = configuration + c +end From 2fef6ed72ab671aab9693281c2eaa1f4ad9615de Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Mon, 11 May 2015 15:01:52 +0100 Subject: [PATCH 039/812] Minor improvement to test coverage --- spec/java_buildpack/component/java_opts_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/java_buildpack/component/java_opts_spec.rb b/spec/java_buildpack/component/java_opts_spec.rb index 4333f0f65e..cb426775fc 100644 --- a/spec/java_buildpack/component/java_opts_spec.rb +++ b/spec/java_buildpack/component/java_opts_spec.rb @@ -41,6 +41,12 @@ expect(opts).to include('-Dtest-key=test-value') end + it 'adds a bootclasspath property to the collection' do + opts.add_bootclasspath_p droplet.sandbox + 'test-bootclasspath' + + expect(opts).to include('-Xbootclasspath/p:$PWD/.java-buildpack/java_opts/test-bootclasspath') + end + it 'adds a qualified option to the collection' do opts.add_option 'test-key', droplet.sandbox From bf43ac99557e79ac0357a1d6b5bf6758192abe42 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 11 May 2015 17:37:22 +0100 Subject: [PATCH 040/812] Quote Happy Previously there were an extra set of quotes around the $CALCULATED_MEMORY option added by the JRE. This set of quotes caused problems for some containers. These quotes have been removed. [resolves #186] --- lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 17d70b6dee..fb38af49eb 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -50,7 +50,7 @@ def memory_calculation_command # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.java_opts.add_preformatted_options '"$CALCULATED_MEMORY"' + @droplet.java_opts.add_preformatted_options '$CALCULATED_MEMORY' end protected diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 815bb1477e..2085b2f703 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -96,7 +96,7 @@ it 'adds $CALCULATED_MEMORY to the JAVA_OPTS' do component.release - expect(java_opts).to include('"$CALCULATED_MEMORY"') + expect(java_opts).to include('$CALCULATED_MEMORY') end end From 3ab58c2d0a995a22a6497c8f4203cb6f8628bff5 Mon Sep 17 00:00:00 2001 From: Stuart Charlton Date: Fri, 15 May 2015 01:43:31 -0600 Subject: [PATCH 041/812] Add memory_limit context to compile tests due to memory calculator -totMemory option that must be > 0 --- spec/bin/compile_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/bin/compile_spec.rb b/spec/bin/compile_spec.rb index b10b4960f6..3ea3254ef4 100644 --- a/spec/bin/compile_spec.rb +++ b/spec/bin/compile_spec.rb @@ -16,12 +16,15 @@ require 'spec_helper' require 'integration_helper' +require 'memory_limit_helper' describe 'compile script', :integration do # rubocop:disable RSpec/DescribeClass include_context 'integration_helper' + include_context 'memory_limit_helper' it 'returns zero if success', - app_fixture: 'integration_valid' do + app_fixture: 'integration_valid', + memory_limit: '1024m' do run("bin/compile #{app_dir} #{app_dir + '.cache'}") { |status| expect(status).to be_success } end From d7ca8cf9cc87daa56c18e78867c462dbd5d29e71 Mon Sep 17 00:00:00 2001 From: Stuart Charlton Date: Thu, 14 May 2015 21:00:53 -0600 Subject: [PATCH 042/812] Dynatrace (www.dynatrace.com) 6.x+ framework support for Java buildpack includes facilities for generically supporting -agentpath with properties as a JVM option Currently disabled, as with Introscope there is no public repository for Dynatrace yet (I've spoken to Dynatrace and they're looking into doing this) --- README.md | 1 + config/components.yml | 1 + config/dyna_trace_agent.yml | 19 ++++ docs/framework-dyna_trace_agent.md | 97 ++++++++++++++++++ lib/java_buildpack/component/java_opts.rb | 10 ++ .../framework/dyna_trace_agent.rb | 95 +++++++++++++++++ spec/fixtures/stub-dyna-trace-agent.jar | Bin 0 -> 1288 bytes .../component/java_opts_spec.rb | 12 +++ .../framework/dyna_trace_agent_spec.rb | 70 +++++++++++++ 9 files changed, 305 insertions(+) create mode 100644 config/dyna_trace_agent.yml create mode 100644 docs/framework-dyna_trace_agent.md create mode 100644 lib/java_buildpack/framework/dyna_trace_agent.rb create mode 100644 spec/fixtures/stub-dyna-trace-agent.jar create mode 100644 spec/java_buildpack/framework/dyna_trace_agent_spec.rb diff --git a/README.md b/README.md index f61b13c2b1..7ef68cd1a9 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) + * [DynaTrace Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 3612c67cb4..811a9147d0 100644 --- a/config/components.yml +++ b/config/components.yml @@ -34,6 +34,7 @@ jres: frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" # - "JavaBuildpack::Framework::IntroscopeAgent" +# - "JavaBuildpack::Framework::DynaTraceAgent" - "JavaBuildpack::Framework::JavaOpts" - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::MariaDbJDBC" diff --git a/config/dyna_trace_agent.yml b/config/dyna_trace_agent.yml new file mode 100644 index 0000000000..84293020d8 --- /dev/null +++ b/config/dyna_trace_agent.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright (c) 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Dynatrace framework +--- +version: 6.1.0_+ +repository_root: "" diff --git a/docs/framework-dyna_trace_agent.md b/docs/framework-dyna_trace_agent.md new file mode 100644 index 0000000000..0e6df74dd2 --- /dev/null +++ b/docs/framework-dyna_trace_agent.md @@ -0,0 +1,97 @@ +# DynaTrace Agent Framework +The DynaTrace Agent Framework causes an application to be automatically configured to work with a bound [DynaTrace Service][] instance (Free trials available). + +The Cloud Foundry pushed application name is used as the `agent group` in DynaTrace, and must be pre-configured on the DynaTrace server. +A system profile may be provided as an optional argument (defaults to `Monitoring`). + +**Current Issues:** +* The DynaTrace agent slows down app execution significantly at first, but gets faster over time. You may want to update your CF deployment manifest to set `maximum_health_check_timeout` to 180 or more and/or execute `cf push -t 180` or more when pushing a DynaTrace-monitored application. + +* As you `cf push` multiple times, many dead penguins will litter the DynaTrace agent dashboard, as CF launches/disposes application containers. These can be hidden but will collect in the dynatrace database. + +
+ + + + + + + +
Detection CriterionExistence of a single bound DynaTrace service. +
    +
  • Existence of a DynaTrace service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has dynatrace as a substring.
  • +
+
Tagsdyna-trace-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +Users must provide their own DynaTrace service. A user-provided DynaTrace service must have a name or tag with `dynatrace` in it so that the DynaTrace Agent Framework will automatically configure the application to work with the service. + +The credential payload of the service may contain the following entries: + +| Name | Description +| ---- | ----------- +| `server` | The DynaTrace collector hostname to connect to. Use `host:port` format for a specific port number. +| `profile` | (optional) The DynaTrace server profile this is associated with. Uses `Monitoring` by default. + +**NOTE** Be sure to open an Application Security Group to your DynaTrace collector prior to starting your application: +``` +$ cat security.json + [ + { + "protocol": "tcp", + "destination": "dynatrace_host", + "ports": "9998" + } + ] + +$ cf create-security-group dynatrace_group ./security.json +Creating security group dynatrace_group as admin +OK + +$ cf bind-running-security-group dynatrace_group +Binding security group dynatrace_group to defaults for running as admin +OK + +TIP: Changes will not apply to existing running applications until they are restarted. +``` + +## Configuration +For general information on configuring the buildpack, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`dyna_trace_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the DynaTrace repository index ([details][repositories]). +| `version` | The version of DynaTrace to use. This buildpack framework has been tested on 6.1.0. + + +**NOTE:** This framework does not connect to a pre-populated repository. Instead you will need to create your own repository by: + +1. Downloading the DynaTrace agent unix binary (in JAR format) to an HTTP-accesible location +1. Uploading an `index.yml` file with a mapping from the version of the agent to its location to the same HTTP-accessible location +1. Configuring the [`dyna_trace_agent.yml`][] file to point to the root of the repository holding both the index and agent binary + +Sample **`repository_root`** for [`dyna_trace_agent.yml`][] (under java-buildpack/config) assuming a bosh-lite setup and a local webserver (e.g. `brew install tomcat7`) on port 8080 + +``` +repository_root: "http://files.192.168.50.1.xip.io:8080/fileserver/dynatrace" +``` + +The buildpack would look for an **`index.yml`** file at the specified **repository_root** for obtaining the DynaTrace agent. + +The index.yml at the repository_root location should have a entry matching the DynaTrace version and the corresponding DynaTrace agent download JAR + +``` +--- +6.1.0.7880: http://files.192.168.50.1.xip.io:8080/fileserver/dynatrace/dynatrace-agent-6.1.0.7880-unix.jar +``` + +Ensure the DynaTrace binary is available at the location indicated by the index.yml referred by the DynaTrace repository_root. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[`dyna_trace_agent.yml`]: ../config/dyna_trace_agent.yml +[DynaTrace Service]: https://dynatrace.com +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index 7041128e78..035329c1f8 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -42,6 +42,16 @@ def add_javaagent(path) add_preformatted_options "-javaagent:#{qualify_path path}" end + # Adds a +agentpath+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to + # ensure that the path is always accurate. + # + # @param [Pathname] path the path to the +agentpath+ shared library + # @param [Properties] properties to append to the agentpath entry + # @return [JavaOpts] +self+ for chaining + def add_agentpath_with_props(path, props) + add_preformatted_options "-agentpath:#{qualify_path path}=" + props.map { |k, v| "#{k}=#{v}" }.join(',') + end + # Adds an +agentpath+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to # ensure that the path is always accurate. # diff --git a/lib/java_buildpack/framework/dyna_trace_agent.rb b/lib/java_buildpack/framework/dyna_trace_agent.rb new file mode 100644 index 0000000000..453d1dc55b --- /dev/null +++ b/lib/java_buildpack/framework/dyna_trace_agent.rb @@ -0,0 +1,95 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/qualify_path' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Dynatrace support. + class DynaTraceAgent < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_zip false + @droplet.copy_resources + FileUtils.mkdir(home_dir) + FileUtils.mv(@droplet.sandbox + 'agent/linux-x86-64/agent', home_dir) + delete_extra_files + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts + .add_agentpath_with_props(agent_dir + 'libdtagent.so', + name: application_name + '_' + profile_name, + server: server) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, 'server' + end + + private + + FILTER = /dynatrace/.freeze + + private_constant :FILTER + + def application_name + @application.details['application_name'] + end + + def profile_name + @application.services.find_service(FILTER)['credentials']['profile'] || 'Monitoring' + end + + def agent_dir + @droplet.sandbox + 'home/agent/lib64' + end + + def delete_extra_files + FileUtils.rm_rf(@droplet.sandbox + 'agent') + FileUtils.rm_rf(@droplet.sandbox + 'init.d') + FileUtils.rm_rf(@droplet.sandbox + 'com') + FileUtils.rm_rf(@droplet.sandbox + 'org') + FileUtils.rm_rf(@droplet.sandbox + 'META_INF') + FileUtils.rm_f(@droplet.sandbox + 'YouShouldNotHaveUnzippedMe.txt') + end + + def logs_dir + @droplet.sandbox + 'home/log' + end + + def home_dir + @droplet.sandbox + 'home' + end + + def server + @application.services.find_service(FILTER)['credentials']['server'] + end + + end + + end +end diff --git a/spec/fixtures/stub-dyna-trace-agent.jar b/spec/fixtures/stub-dyna-trace-agent.jar new file mode 100644 index 0000000000000000000000000000000000000000..558673445672aa313d41c7168c02b9dbd42c653c GIT binary patch literal 1288 zcmWIWW@h1H00GuIdp9rxO0Y4=FeIj@=9TD&hHx@4uZ%t$5;@^)NNEK(10%~fMg|5J z5unNdoce{~`g1b#N-K0LEX;JxOo%j$1I;m#*bPH+-+EHrCx_3-I=2Urn z=H_H3!NOoSAqS%ytV7sfpz$ds;6TwU&Id;u$QBUB8ExWoP@^3bERp%8!5R6bIVpbm zB_4@osiApQnFR%@DZZ(CB^4!LbA5qH0faHkWn_|L#+9HXph-)B;jJTx35z~fNb(}V zEMW#@vmD@Np(QoK24f~PWP^LL8;s;`P_iSz-Et`Iet^$-Xc8ps1@v?xk79=fFsDM? zixM_4AxLrrT7or^AR-gp5*@fD3=B&eCla;_E7fiGjf%h#43FCtUvH literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/component/java_opts_spec.rb b/spec/java_buildpack/component/java_opts_spec.rb index cb426775fc..e835050e03 100644 --- a/spec/java_buildpack/component/java_opts_spec.rb +++ b/spec/java_buildpack/component/java_opts_spec.rb @@ -29,6 +29,18 @@ expect(opts).to include('-javaagent:$PWD/.java-buildpack/java_opts/test-java-agent') end + it 'adds a qualified agentpath to the collection' do + opts.add_agentpath droplet.sandbox + 'test-agentpath' + + expect(opts).to include('-agentpath:$PWD/.java-buildpack/java_opts/test-agentpath') + end + + it 'adds a qualified agentpath with properties to the collection' do + opts.add_agentpath_with_props(droplet.sandbox + 'test-agentpath', 'key1' => 'value1', 'key2' => 'value2') + + expect(opts).to include('-agentpath:$PWD/.java-buildpack/java_opts/test-agentpath=key1=value1,key2=value2') + end + it 'adds a qualified system property to the collection' do opts.add_system_property 'test-key', droplet.sandbox diff --git a/spec/java_buildpack/framework/dyna_trace_agent_spec.rb b/spec/java_buildpack/framework/dyna_trace_agent_spec.rb new file mode 100644 index 0000000000..7e82f0defe --- /dev/null +++ b/spec/java_buildpack/framework/dyna_trace_agent_spec.rb @@ -0,0 +1,70 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/dyna_trace_agent' + +describe JavaBuildpack::Framework::DynaTraceAgent do + include_context 'component_helper' + + it 'does not detect without dynatrace-n/a service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?).with(/dynatrace/, 'server').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name' }) + end + + it 'detects with dynatrace-n/a service' do + expect(component.detect).to eq("dyna-trace-agent=#{version}") + end + + it 'expands DynaTrace agent zip', + cache_fixture: 'stub-dyna-trace-agent.jar' do + + component.compile + expect(sandbox + 'home/agent/lib64/libdtagent.so').to exist + expect(sandbox + 'YouShouldNotHaveUnzippedMe.txt').not_to exist + end + + it 'updates JAVA_OPTS' do + component.release + expect(java_opts).to include( + '-agentpath:$PWD/.java-buildpack/dyna_trace_agent/home/agent/lib64/'\ + 'libdtagent.so=name=test-application-name_Monitoring,server=test-host-name') + end + end + + context do + before do + allow(services).to receive(:one_service?).with(/dynatrace/, 'server').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name', + 'profile' => 'test-profile' }) + end + + it 'updates JAVA_OPTS with custom profile' do + component.release + expect(java_opts).to include( + '-agentpath:$PWD/.java-buildpack/dyna_trace_agent/home/agent/lib64/'\ + 'libdtagent.so=name=test-application-name_test-profile,server=test-host-name') + end + + end +end From 06cbb3636acb99f9ec8623aec9931b5b4de376fc Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 20 May 2015 14:04:47 +0100 Subject: [PATCH 043/812] Play Memory Options Formatting This commit causes the output of the memory calculator to be wrapped in a little bash code to apply '-J' to all of the memory settings as required for Play applications. [#94311316] --- lib/java_buildpack/util/play/post22.rb | 2 +- spec/java_buildpack/util/play/post22_spec.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/util/play/post22.rb b/lib/java_buildpack/util/play/post22.rb index 5c8cc102ab..7385c6f5d1 100644 --- a/lib/java_buildpack/util/play/post22.rb +++ b/lib/java_buildpack/util/play/post22.rb @@ -48,7 +48,7 @@ def java_opts fail "Invalid Java option contains more than one option: '#{option}'" end - java_opts.map { |java_opt| "-J#{java_opt}" } + java_opts.map { |option| option == '$CALCULATED_MEMORY' ? '${CALCULATED_MEMORY//-/-J-}' : "-J#{option}" } end # (see JavaBuildpack::Util::Play::Base#lib_dir) diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index 094a1d1d7f..0e5d51e4a8 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -59,6 +59,14 @@ end end + context do + let(:java_opts) { super() << '$CALCULATED_MEMORY' } + + it 'does wraps the output of CALCULATED_MEMORY correctly' do + expect(play_app.release).to include('${CALCULATED_MEMORY//-/-J-}') + end + end + context do let(:java_opts) do super() << '-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : \'.' \ From 543116b3caa52c2b320f6cb0eea866bee8e171ac Mon Sep 17 00:00:00 2001 From: Edin Zulich Date: Wed, 20 May 2015 11:33:05 -0700 Subject: [PATCH 044/812] Update the name and link to GemFire SSC service --- docs/container-tomcat.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index 8f5f49b608..1b08a8932f 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -58,7 +58,7 @@ By default, the Tomcat instance is configured to store all Sessions and their da To enable Redis-based session replication, simply bind a Redis service containing a name, label, or tag that has `session-replication` as a substring. ### GemFire -To enable GemFire-based session replication, simply bind a [GemFire service][] containing a name, label, or tag that has `session_replication` as a substring. GemFire services intended to be used for session replication will automatically have a tag of 'session_replication'. +To enable GemFire-based session replication, simply bind a [Session State Caching (SSC) GemFire service][] containing a name, label, or tag that has `session_replication` as a substring. GemFire services intended to be used for session replication will automatically have a tag of 'session_replication'. ## Managing Entropy Entropy from `/dev/random` is used heavily to create session ids, and on startup for initializing `SecureRandom`, which can then cause instances to fail to start in time (see the [Tomcat wiki]). Also, the entropy is shared so it's possible for a single app to starve the DEA of entropy and cause apps in other containers that make use of entropy to be blocked. @@ -75,7 +75,7 @@ Additional supporting functionality can be found in the [`java-buildpack-support [Configuration and Extension]: ../README.md#configuration-and-extension [`config/tomcat.yml`]: ../config/tomcat.yml -[GemFire Service]: https://network.pivotal.io/products/p-gemfire +[Session State Caching (SSC) GemFire service]: https://network.pivotal.io/products/p-ssc-gemfire [`java-buildpack-support`]: https://github.com/cloudfoundry/java-buildpack-support [repositories]: extending-repositories.md [Spring profiles]:http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/ From f2ca1cd4683c140fa43efcc9ca2cdb333910f228 Mon Sep 17 00:00:00 2001 From: Gareth Evans Date: Wed, 27 May 2015 13:22:27 +0000 Subject: [PATCH 045/812] Corrected JVM configuration example JRE version is now wrapped in a 'jre' element, and the memory_heuristics is now wrapped in a 'memory_calculator' element. Issue: 191 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ef68cd1a9..926b8a9ac7 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ The buildpack supports extension through the use of Git repository forking. The Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. The value of the variable should be valid inline yaml. For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. -```cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '[version: 1.7.0_+, memory_heuristics: {heap: 85, stack: 10}]'``` +```cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '[jre: {version: 1.7.0_+}, memory_calculator: {memory_heuristics: {heap: 85, stack: 10}}]'``` If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. From 08199577998d749edda2d8a868c6c9a50f878b6c Mon Sep 17 00:00:00 2001 From: Claude Devarenne Date: Mon, 1 Jun 2015 15:41:09 -0700 Subject: [PATCH 046/812] download_tar improvements A previous change to the download_tar method introduced a bug where the wrong decompression flag was applied to the tar command. This change fixes that bug, applying the appropriate gzip decompression flag. This change also adds support for bzip2 compressed tar files. [resolves #195] --- lib/java_buildpack/component/base_component.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index e5d968108d..a3bc51fab5 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -122,7 +122,7 @@ def download_tar(version, uri, target_directory = @droplet.sandbox, name = @comp download(version, uri, name) do |file| with_timing "Expanding #{name} to #{target_directory.relative_path_from(@droplet.root)}" do FileUtils.mkdir_p target_directory - shell "tar x#{gzipped?(file) ? 'x' : ''}f #{file.path} -C #{target_directory} --strip 1 2>&1" + shell "tar x#{compression_flag(file)}f #{file.path} -C #{target_directory} --strip 1 2>&1" end end end @@ -172,6 +172,20 @@ def gzipped?(file) file.path.end_with? '.gz' end + def bzipped?(file) + file.path.end_with? '.bz2' + end + + def compression_flag(file) + if gzipped?(file) + 'z' + elsif bzipped?(file) + 'j' + else + '' + end + end + end end From 1393184eeadc891a00679b8d293937e92be0b826 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Fri, 12 Jun 2015 17:18:20 +0100 Subject: [PATCH 047/812] Refactor the Dynatrace support This commit moves the Dynatrace to be inline with the other supported frameworks. Also includes updates to the documentation. The support has been tested against a live Dynatrace server. [#95410056] --- docs/framework-dyna_trace_agent.md | 46 ++++---------- .../framework/dyna_trace_agent.rb | 60 +++++++++++-------- .../framework/dyna_trace_agent_spec.rb | 7 +-- 3 files changed, 51 insertions(+), 62 deletions(-) diff --git a/docs/framework-dyna_trace_agent.md b/docs/framework-dyna_trace_agent.md index 0e6df74dd2..d6bcc678a5 100644 --- a/docs/framework-dyna_trace_agent.md +++ b/docs/framework-dyna_trace_agent.md @@ -1,13 +1,12 @@ # DynaTrace Agent Framework The DynaTrace Agent Framework causes an application to be automatically configured to work with a bound [DynaTrace Service][] instance (Free trials available). -The Cloud Foundry pushed application name is used as the `agent group` in DynaTrace, and must be pre-configured on the DynaTrace server. -A system profile may be provided as an optional argument (defaults to `Monitoring`). +The applications Cloud Foundry name is used as the `agent group` in DynaTrace, and must be pre-configured on the DynaTrace server. -**Current Issues:** -* The DynaTrace agent slows down app execution significantly at first, but gets faster over time. You may want to update your CF deployment manifest to set `maximum_health_check_timeout` to 180 or more and/or execute `cf push -t 180` or more when pushing a DynaTrace-monitored application. +**NOTE** -* As you `cf push` multiple times, many dead penguins will litter the DynaTrace agent dashboard, as CF launches/disposes application containers. These can be hidden but will collect in the dynatrace database. +* The DynaTrace agent slows down app execution significantly at first, but gets faster over time. Setting the application manifest to contain `maximum_health_check_timeout` of 180 or more and/or using `cf push -t 180` or more when pushing a DynaTrace-monitored application may help. +* Multiple `cf push`s will cause dead penguins to build up in the DynaTrace agent dashboard, as CF launches/disposes application containers. These can be hidden but will collect in the dynatrace database. @@ -31,10 +30,12 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- -| `server` | The DynaTrace collector hostname to connect to. Use `host:port` format for a specific port number. -| `profile` | (optional) The DynaTrace server profile this is associated with. Uses `Monitoring` by default. +| `server` | The DynaTrace collector hostname to connect to. Use `host:port` format for a specific port number. +| `profile` | (Optional) The DynaTrace server profile this is associated with. Uses `Monitoring` by default. -**NOTE** Be sure to open an Application Security Group to your DynaTrace collector prior to starting your application: +**NOTE** + +Be sure to open an Application Security Group to your DynaTrace collector prior to starting the application: ``` $ cat security.json [ @@ -59,39 +60,18 @@ TIP: Changes will not apply to existing running applications until they are rest ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. -The framework can be configured by modifying the [`dyna_trace_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. +The framework can be configured by modifying the [`config/dyna_trace_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. | Name | Description | ---- | ----------- | `repository_root` | The URL of the DynaTrace repository index ([details][repositories]). | `version` | The version of DynaTrace to use. This buildpack framework has been tested on 6.1.0. - -**NOTE:** This framework does not connect to a pre-populated repository. Instead you will need to create your own repository by: - -1. Downloading the DynaTrace agent unix binary (in JAR format) to an HTTP-accesible location -1. Uploading an `index.yml` file with a mapping from the version of the agent to its location to the same HTTP-accessible location -1. Configuring the [`dyna_trace_agent.yml`][] file to point to the root of the repository holding both the index and agent binary - -Sample **`repository_root`** for [`dyna_trace_agent.yml`][] (under java-buildpack/config) assuming a bosh-lite setup and a local webserver (e.g. `brew install tomcat7`) on port 8080 - -``` -repository_root: "http://files.192.168.50.1.xip.io:8080/fileserver/dynatrace" -``` - -The buildpack would look for an **`index.yml`** file at the specified **repository_root** for obtaining the DynaTrace agent. - -The index.yml at the repository_root location should have a entry matching the DynaTrace version and the corresponding DynaTrace agent download JAR - -``` ---- -6.1.0.7880: http://files.192.168.50.1.xip.io:8080/fileserver/dynatrace/dynatrace-agent-6.1.0.7880-unix.jar -``` - -Ensure the DynaTrace binary is available at the location indicated by the index.yml referred by the DynaTrace repository_root. +### Additional Resources +The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/ca_wily_agent` directory in the buildpack fork. For example, to override the default profile add your custom profile to `resources/introscope_agent/`. [Configuration and Extension]: ../README.md#configuration-and-extension -[`dyna_trace_agent.yml`]: ../config/dyna_trace_agent.yml +[`config/dyna_trace_agent.yml`]: ../config/dyna_trace_agent.yml [DynaTrace Service]: https://dynatrace.com [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/dyna_trace_agent.rb b/lib/java_buildpack/framework/dyna_trace_agent.rb index 453d1dc55b..dfdd2448b7 100644 --- a/lib/java_buildpack/framework/dyna_trace_agent.rb +++ b/lib/java_buildpack/framework/dyna_trace_agent.rb @@ -28,19 +28,14 @@ class DynaTraceAgent < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_zip false + download(@version, @uri) { |file| expand file } @droplet.copy_resources - FileUtils.mkdir(home_dir) - FileUtils.mv(@droplet.sandbox + 'agent/linux-x86-64/agent', home_dir) - delete_extra_files end # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.java_opts - .add_agentpath_with_props(agent_dir + 'libdtagent.so', - name: application_name + '_' + profile_name, - server: server) + @droplet.java_opts.add_agentpath_with_props(agent_path, name: agent_name, server: server) + # -agentpath:=name=Tomcat_Monitoring,server=ubuntu:9998 end protected @@ -56,33 +51,48 @@ def supports? private_constant :FILTER - def application_name - @application.details['application_name'] + def agent_dir + @droplet.sandbox + 'agent' end - def profile_name - @application.services.find_service(FILTER)['credentials']['profile'] || 'Monitoring' + def agent_path + agent_dir + lib_name + 'libdtagent.so' end - def agent_dir - @droplet.sandbox + 'home/agent/lib64' + def agent_name + "#{@application.details['application_name']}_#{profile_name}" + end + + def architecture + `uname -m`.strip end - def delete_extra_files - FileUtils.rm_rf(@droplet.sandbox + 'agent') - FileUtils.rm_rf(@droplet.sandbox + 'init.d') - FileUtils.rm_rf(@droplet.sandbox + 'com') - FileUtils.rm_rf(@droplet.sandbox + 'org') - FileUtils.rm_rf(@droplet.sandbox + 'META_INF') - FileUtils.rm_f(@droplet.sandbox + 'YouShouldNotHaveUnzippedMe.txt') + def expand(file) + with_timing "Expanding Dynatrace to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do + Dir.mktmpdir do |root| + root_path = Pathname.new(root) + shell "unzip -qq #{file.path} -d #{root_path} 2>&1" + unpack_agent root_path + end + end end - def logs_dir - @droplet.sandbox + 'home/log' + def lib_name + architecture == 'x86_64' || architecture == 'i686' ? 'lib64' : 'lib' end - def home_dir - @droplet.sandbox + 'home' + def agent_unpack_path + architecture == 'x86_64' || architecture == 'i686' ? 'linux-x86-64/agent' : 'linux-x86-32/agent' + end + + def unpack_agent(root) + FileUtils.mkdir_p(agent_dir) + FileUtils.mv(root + 'agent' + agent_unpack_path + 'conf', agent_dir) + FileUtils.mv(root + 'agent' + agent_unpack_path + lib_name, agent_dir) + end + + def profile_name + @application.services.find_service(FILTER)['credentials']['profile'] || 'Monitoring' end def server diff --git a/spec/java_buildpack/framework/dyna_trace_agent_spec.rb b/spec/java_buildpack/framework/dyna_trace_agent_spec.rb index 7e82f0defe..24768810f6 100644 --- a/spec/java_buildpack/framework/dyna_trace_agent_spec.rb +++ b/spec/java_buildpack/framework/dyna_trace_agent_spec.rb @@ -40,14 +40,13 @@ cache_fixture: 'stub-dyna-trace-agent.jar' do component.compile - expect(sandbox + 'home/agent/lib64/libdtagent.so').to exist - expect(sandbox + 'YouShouldNotHaveUnzippedMe.txt').not_to exist + expect(sandbox + 'agent/lib64/libdtagent.so').to exist end it 'updates JAVA_OPTS' do component.release expect(java_opts).to include( - '-agentpath:$PWD/.java-buildpack/dyna_trace_agent/home/agent/lib64/'\ + '-agentpath:$PWD/.java-buildpack/dyna_trace_agent/agent/lib64/'\ 'libdtagent.so=name=test-application-name_Monitoring,server=test-host-name') end end @@ -62,7 +61,7 @@ it 'updates JAVA_OPTS with custom profile' do component.release expect(java_opts).to include( - '-agentpath:$PWD/.java-buildpack/dyna_trace_agent/home/agent/lib64/'\ + '-agentpath:$PWD/.java-buildpack/dyna_trace_agent/agent/lib64/'\ 'libdtagent.so=name=test-application-name_test-profile,server=test-host-name') end From e60bd74bf970b3834d4bf7b53254676f6d720499 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 17 Jun 2015 15:51:47 +0100 Subject: [PATCH 048/812] Fix failing tc buildpack tests This commit moves some changes from the tc-server buildpack up to the Java buildpack in order to avoid mutating delta with the tc-server buildpack. These changes are required to get the tc-server system tests passing. [#96170478] --- java-buildpack.iml | 2 +- .../component/immutable_java_home.rb | 6 +- .../component/mutable_java_home.rb | 2 +- lib/java_buildpack/container/java_main.rb | 4 +- .../component/immutable_java_home_spec.rb | 2 +- .../container/java_main_spec.rb | 57 ++++++++++--------- 6 files changed, 39 insertions(+), 34 deletions(-) diff --git a/java-buildpack.iml b/java-buildpack.iml index a047a3fd77..7aff0361b0 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -271,7 +271,7 @@ - + diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index afcf3bd6df..488323afb5 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -39,7 +39,7 @@ def initialize(delegate, droplet_root) # # @return [String] the path of +JAVA_HOME+ as an environment variable def as_env_var - "JAVA_HOME=#{root}" + "JAVA_HOME=#{qualify_path root}" end # Whether or not the version of Java is 8 or later @@ -49,9 +49,9 @@ def java_8_or_later? @delegate.java_8_or_later? end - # @return [String] the root of the droplet's +JAVA_HOME+ formatted as +$PWD/+ + # @return [Pathname] the root of the droplet's +JAVA_HOME+ def root - qualify_path @delegate.root + @delegate.root end # @return # @return [JavaBuildpack::Util::TokenizedVersion] the tokenized droplet's +VERSION+ diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index 6092f5f48f..f911903b62 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -35,7 +35,7 @@ class MutableJavaHome attr_accessor :version # Whether or not the version of Java is 8 or later - # @return [Boolean] +true+ iff the version is 1.8.0 or later + # @return [Boolean] +true+ if the version is 1.8.0 or later def java_8_or_later? @version >= VERSION_8 end diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index 55108445e7..799ecce891 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -18,6 +18,7 @@ require 'java_buildpack/container' require 'java_buildpack/util/dash_case' require 'java_buildpack/util/java_main_utils' +require 'java_buildpack/util/qualify_path' module JavaBuildpack module Container @@ -26,6 +27,7 @@ module Container # method. This isn't a _container_ in the traditional sense, but contains the functionality to manage the lifecycle # of Java +main()+ applications. class JavaMain < JavaBuildpack::Component::BaseComponent + include JavaBuildpack::Util # (see JavaBuildpack::Component::BaseComponent#detect) def detect @@ -55,7 +57,7 @@ def release def release_text [ port, - "#{@droplet.java_home.root}/bin/java", + "#{qualify_path @droplet.java_home.root, @droplet.root}/bin/java", @droplet.additional_libraries.as_classpath, @droplet.java_opts.join(' '), main_class, diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index 5c3a95a44a..4ae9e733a9 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -34,7 +34,7 @@ end it 'returns the qualified delegate root' do - expect(immutable_java_home.root).to eq('$PWD/test-java-home') + expect(immutable_java_home.root.to_s).to eq('test-java-home') end it 'returns the delegate version' do diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index 10e18cbc88..9f5ccaecfe 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -17,8 +17,10 @@ require 'spec_helper' require 'component_helper' require 'java_buildpack/container/java_main' +require 'java_buildpack/util/qualify_path' describe JavaBuildpack::Container::JavaMain do + include JavaBuildpack::Util include_context 'component_helper' shared_context 'explicit_main_class' do @@ -57,18 +59,18 @@ it 'returns command' do - expect(component.release).to eq("#{java_home.root}/bin/java -cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:" \ - "$PWD/.additional_libs/test-jar-2.jar #{java_opts_str} " \ - 'test-java-main-class') + expect(component.release).to eq("#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD/.:$PWD/." \ + 'additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ + " #{java_opts_str} test-java-main-class") end end it 'returns additional classpath entries when Class-Path is specified', app_fixture: 'container_main' do - expect(component.release).to eq("#{java_home.root}/bin/java -cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:" \ - '$PWD/.additional_libs/test-jar-2.jar:$PWD/alpha.jar:$PWD/bravo.jar:' \ - "$PWD/charlie.jar #{java_opts_str} test-main-class") + expect(component.release).to eq("#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD/.:$PWD/." \ + 'additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar:$PWD/' \ + "alpha.jar:$PWD/bravo.jar:$PWD/charlie.jar #{java_opts_str} test-main-class") end context do @@ -76,34 +78,34 @@ it 'returns command line arguments when they are specified' do - expect(component.release).to eq("#{java_home.root}/bin/java -cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:" \ - "$PWD/.additional_libs/test-jar-2.jar #{java_opts_str} " \ - 'test-java-main-class some arguments') + expect(component.release).to eq("#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD/.:$PWD/." \ + 'additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ + " #{java_opts_str} test-java-main-class some arguments") end end it 'releases Spring boot applications with a JarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_jar_launcher' do - expect(component.release).to eq("SERVER_PORT=$PORT #{java_home.root}/bin/java -cp $PWD/.:" \ - '$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ - "#{java_opts_str} org.springframework.boot.loader.JarLauncher") + expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ + " #{java_opts_str} org.springframework.boot.loader.JarLauncher") end it 'releases Spring boot applications with a WarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_war_launcher' do - expect(component.release).to eq("SERVER_PORT=$PORT #{java_home.root}/bin/java -cp $PWD/.:" \ - '$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ - "#{java_opts_str} org.springframework.boot.loader.WarLauncher") + expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ + " #{java_opts_str} org.springframework.boot.loader.WarLauncher") end it 'releases Spring boot applications with a PropertiesLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_properties_launcher' do - expect(component.release).to eq("SERVER_PORT=$PORT #{java_home.root}/bin/java -cp $PWD/.:" \ - '$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ - "#{java_opts_str} org.springframework.boot.loader.PropertiesLauncher") + expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ + " #{java_opts_str} org.springframework.boot.loader.PropertiesLauncher") end context do @@ -111,9 +113,9 @@ it 'releases Spring boot applications with a JarLauncher in the configuration by specifying a port' do - expect(component.release).to eq("SERVER_PORT=$PORT #{java_home.root}/bin/java -cp $PWD/.:" \ - '$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ - "#{java_opts_str} org.springframework.boot.loader.JarLauncher") + expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp " \ + '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + "test-jar-2.jar #{java_opts_str} org.springframework.boot.loader.JarLauncher") end end @@ -122,9 +124,9 @@ it 'releases Spring boot applications with a WarLauncher in the configuration by specifying a port' do - expect(component.release).to eq("SERVER_PORT=$PORT #{java_home.root}/bin/java -cp $PWD/.:" \ - '$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ - "#{java_opts_str} org.springframework.boot.loader.WarLauncher") + expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp " \ + '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + "test-jar-2.jar #{java_opts_str} org.springframework.boot.loader.WarLauncher") end end @@ -133,9 +135,10 @@ it 'releases Spring boot applications with a PropertiesLauncher in the configuration by specifying a port' do - expect(component.release).to eq("SERVER_PORT=$PORT #{java_home.root}/bin/java -cp $PWD/.:" \ - '$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ - "#{java_opts_str} org.springframework.boot.loader.PropertiesLauncher") + expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs' \ + "/test-jar-2.jar #{java_opts_str} org.springframework.boot.loader." \ + 'PropertiesLauncher') end end From b87847f11db20b1877652c03f9084330c712a3c1 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 17 Jun 2015 17:26:13 +0100 Subject: [PATCH 049/812] Revert Java doc change iff actually means 'if and only if', updating Java Doc. --- lib/java_buildpack/component/mutable_java_home.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index f911903b62..d6067b82f3 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -35,7 +35,7 @@ class MutableJavaHome attr_accessor :version # Whether or not the version of Java is 8 or later - # @return [Boolean] +true+ if the version is 1.8.0 or later + # @return [Boolean] +true+ if and only if the version is 1.8.0 or later def java_8_or_later? @version >= VERSION_8 end From ad899698d2719ae2fd33f8cd29a773be3621eeb4 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 23 Jun 2015 15:08:34 +0100 Subject: [PATCH 050/812] Pin versions in the offline buildpack This commit allows a PINNED=true option to be set when building an offline buildpack that will pin the versions of all buildpack dependencies to the currently resolved versions. This will result in changes to the contents of configuration files in the config directory. [#93987158] --- README.md | 4 +- config/app_dynamics_agent.yml | 4 +- config/groovy.yml | 2 +- config/jrebel_agent.yml | 2 +- config/maria_db_jdbc.yml | 2 +- config/new_relic_agent.yml | 2 +- config/open_jdk_jre.yml | 4 +- .../play_framework_auto_reconfiguration.yml | 2 +- config/play_framework_jpa_plugin.yml | 2 +- config/postgresql_jdbc.yml | 2 +- config/spring_auto_reconfiguration.yml | 2 +- config/spring_boot_cli.yml | 2 +- config/tomcat.yml | 22 ++++----- .../util/configuration_utils.rb | 45 ++++++++++++++++++- rakelib/dependency_cache_task.rb | 37 ++++++++++++--- .../util/configuration_utils_spec.rb | 21 ++++++--- 16 files changed, 117 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 926b8a9ac7..feeb25e82e 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,11 @@ Creating build/java-buildpack-cfd6b17.zip ### Offline Package The offline package is a version of the buildpack designed to run without access to a network. It packages the latest version of each dependency (as configured in the [`config/` directory][]) and [disables `remote_downloads`][]. This package is about 180M in size. To create the offline package, use the `OFFLINE=true` argument: +To pin the version of dependencies used by the buildpack to the ones currently resolvable use the `PINNED=true` argument. This will update the [`config/` directory][] to contain exact version of each dependency instead of version ranges. + ```bash bundle install -bundle exec rake package OFFLINE=true +bundle exec rake package OFFLINE=true PINNED=true ... Creating build/java-buildpack-offline-cfd6b17.zip ``` diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 31ebf790d9..81e3f0d3a2 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -16,6 +16,6 @@ # Configuration for the New Relic framework --- version: 4.0.+ -repository_root: "{default.repository.root}/app-dynamics" -default_node_name: "$(expr \"$VCAP_APPLICATION\" : \'.*instance_index[\": ]*\\([[:digit:]]*\\).*\')" +repository_root: ! '{default.repository.root}/app-dynamics' +default_node_name: ! '$(expr "$VCAP_APPLICATION" : ''.*instance_index[": ]*\([[:digit:]]*\).*'')' default_tier_name: CloudFoundry diff --git a/config/groovy.yml b/config/groovy.yml index 6ec9823ef5..4ac5d8a823 100644 --- a/config/groovy.yml +++ b/config/groovy.yml @@ -16,4 +16,4 @@ # Configuration for the Groovy container --- version: 2.4.+ -repository_root: "{default.repository.root}/groovy" +repository_root: ! '{default.repository.root}/groovy' diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml index 89d7e8bcfe..7636f4954a 100644 --- a/config/jrebel_agent.yml +++ b/config/jrebel_agent.yml @@ -16,4 +16,4 @@ # Configuration for the JRebel framework --- version: 6.+ -repository_root: "http://dl.zeroturnaround.com/jrebel" +repository_root: http://dl.zeroturnaround.com/jrebel diff --git a/config/maria_db_jdbc.yml b/config/maria_db_jdbc.yml index 77f03d7c0c..ced631ed81 100644 --- a/config/maria_db_jdbc.yml +++ b/config/maria_db_jdbc.yml @@ -16,4 +16,4 @@ # Configuration for the MariaDB JDBC framework --- version: 1.1.+ -repository_root: "{default.repository.root}/mariadb-jdbc" +repository_root: ! '{default.repository.root}/mariadb-jdbc' diff --git a/config/new_relic_agent.yml b/config/new_relic_agent.yml index e0237c7326..23a75f9b84 100644 --- a/config/new_relic_agent.yml +++ b/config/new_relic_agent.yml @@ -16,4 +16,4 @@ # Configuration for the New Relic framework --- version: 3.+ -repository_root: "{default.repository.root}/new-relic" +repository_root: ! '{default.repository.root}/new-relic' diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index a42e8a72c1..b901310268 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -18,10 +18,10 @@ --- jre: version: 1.8.0_+ - repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" + repository_root: ! '{default.repository.root}/openjdk/{platform}/{architecture}' memory_calculator: version: 1.+ - repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' memory_sizes: metaspace: 64m.. permgen: 64m.. diff --git a/config/play_framework_auto_reconfiguration.yml b/config/play_framework_auto_reconfiguration.yml index 63dd0935b3..3243625cef 100644 --- a/config/play_framework_auto_reconfiguration.yml +++ b/config/play_framework_auto_reconfiguration.yml @@ -18,5 +18,5 @@ # avoid conflicts. --- version: 1.+ -repository_root: "{default.repository.root}/auto-reconfiguration" +repository_root: ! '{default.repository.root}/auto-reconfiguration' enabled: true diff --git a/config/play_framework_jpa_plugin.yml b/config/play_framework_jpa_plugin.yml index 1c6df17637..25bed7d7ce 100644 --- a/config/play_framework_jpa_plugin.yml +++ b/config/play_framework_jpa_plugin.yml @@ -16,5 +16,5 @@ # Configuration for the Play JPA Plugin framework --- version: 1.+ -repository_root: "{default.repository.root}/play-jpa-plugin" +repository_root: ! '{default.repository.root}/play-jpa-plugin' enabled: true diff --git a/config/postgresql_jdbc.yml b/config/postgresql_jdbc.yml index 6937a54a65..76a3c04346 100644 --- a/config/postgresql_jdbc.yml +++ b/config/postgresql_jdbc.yml @@ -16,4 +16,4 @@ # Configuration for the Postgresql JDBC framework --- version: 9.4.+ -repository_root: "{default.repository.root}/postgresql-jdbc" +repository_root: ! '{default.repository.root}/postgresql-jdbc' diff --git a/config/spring_auto_reconfiguration.yml b/config/spring_auto_reconfiguration.yml index 128dfc4d16..722e472a15 100644 --- a/config/spring_auto_reconfiguration.yml +++ b/config/spring_auto_reconfiguration.yml @@ -18,5 +18,5 @@ # avoid conflicts. --- version: 1.+ -repository_root: "{default.repository.root}/auto-reconfiguration" +repository_root: ! '{default.repository.root}/auto-reconfiguration' enabled: true diff --git a/config/spring_boot_cli.yml b/config/spring_boot_cli.yml index c1748bb922..bb3491ad03 100644 --- a/config/spring_boot_cli.yml +++ b/config/spring_boot_cli.yml @@ -18,4 +18,4 @@ # avoid conflicts. --- version: 1.+ -repository_root: "{default.repository.root}/spring-boot-cli" +repository_root: ! '{default.repository.root}/spring-boot-cli' diff --git a/config/tomcat.yml b/config/tomcat.yml index 7e5459de99..381842e751 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -17,39 +17,39 @@ --- tomcat: version: 8.0.+ - repository_root: "{default.repository.root}/tomcat" + repository_root: ! '{default.repository.root}/tomcat' lifecycle_support: version: 2.+ - repository_root: "{default.repository.root}/tomcat-lifecycle-support" + repository_root: ! '{default.repository.root}/tomcat-lifecycle-support' logging_support: version: 2.+ - repository_root: "{default.repository.root}/tomcat-logging-support" + repository_root: ! '{default.repository.root}/tomcat-logging-support' access_logging_support: version: 2.+ - repository_root: "{default.repository.root}/tomcat-access-logging-support" + repository_root: ! '{default.repository.root}/tomcat-access-logging-support' access_logging: disabled redis_store: version: 1.+ - repository_root: "{default.repository.root}/redis-store" + repository_root: ! '{default.repository.root}/redis-store' database: 0 timeout: 2000 connection_pool_size: 2 gemfire_store: gemfire: version: 8.0.+ - repository_root: "{default.repository.root}/gem-fire" + repository_root: ! '{default.repository.root}/gem-fire' gemfire_modules: version: 8.0.+ - repository_root: "{default.repository.root}/gem-fire-modules" + repository_root: ! '{default.repository.root}/gem-fire-modules' gemfire_modules_tomcat7: version: 8.0.+ - repository_root: "{default.repository.root}/gem-fire-modules-tomcat7" + repository_root: ! '{default.repository.root}/gem-fire-modules-tomcat7' gemfire_security: version: 8.0.+ - repository_root: "{default.repository.root}/gem-fire-security" + repository_root: ! '{default.repository.root}/gem-fire-security' gemfire_logging: version: 1.5.8 - repository_root: "{default.repository.root}/slf4j-jdk14" + repository_root: ! '{default.repository.root}/slf4j-jdk14' gemfire_logging_api: version: 1.5.8 - repository_root: "{default.repository.root}/slf4j-api" + repository_root: ! '{default.repository.root}/slf4j-api' diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index ed645aabc4..e493b11422 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -34,12 +34,12 @@ class << self # exist, returns an empty hash. Overlays configuration in a matching environment variable, on top of the loaded # configuration, if present. Will not add a new configuration key where an existing one does not exist. # - # @param [String] identifier the identifier of the configuration + # @param [String] identifier the identifier of the configuration to load # @param [Boolean] should_log whether the contents of the configuration file should be logged. This value # should be left to its default and exists to allow the logger to use the utility. # @return [Hash] the configuration or an empty hash if the configuration file does not exist def load(identifier, should_log = true) - file = CONFIG_DIRECTORY + "#{identifier}.yml" + file = file_name(identifier) if file.exist? user_provided = ENV[environment_variable_name(identifier)] @@ -51,6 +51,31 @@ def load(identifier, should_log = true) configuration || {} end + # Write a new configuration file to the buildpack configuration directory. Any existing file will be replaced. + # + # @param [String] identifier the identifier of the configuration to write + # @param [Boolean] should_log whether the contents of the configuration file should be logged. This value + # should be left to its default and exists to allow the logger to use the utility. + def write(identifier, new_content, should_log = true) + file = file_name(identifier) + + if file.exist? + logger.debug { "Writing configuration file #{file}" } if should_log + header = header(file) + + File.open(file, 'w') do |f| + header.each { |line| f.write line} + # f.write(header.join('\n')) + # f.write('\n') + YAML.dump(new_content, f) + end + else + logger.debug { "No configuration file #{file} found" } if should_log + end + + end + + private CONFIG_DIRECTORY = Pathname.new(File.expand_path('../../../config', File.dirname(__FILE__))).freeze @@ -59,6 +84,22 @@ def load(identifier, should_log = true) private_constant :CONFIG_DIRECTORY, :ENVIRONMENT_VARIABLE_PATTERN + def file_name(identifier) + CONFIG_DIRECTORY + "#{identifier}.yml" + end + + def header(file) + header = [] + File.open(file, 'r') do |f| + f.each do |line| + break if line =~ /^---/ + fail unless line =~ /^#/ || line =~ /^$/ + header << line + end + end + header + end + def load_configuration(file, user_provided, should_log) configuration = YAML.load_file(file) logger.debug { "Configuration from #{file}: #{configuration}" } if should_log diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 7950a84a0e..908a82d6df 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -21,6 +21,7 @@ require 'java_buildpack/util/configuration_utils' require 'java_buildpack/util/cache/download_cache' require 'java_buildpack/util/snake_case' +require 'monitor' require 'rake/tasklib' require 'rakelib/package' require 'pathname' @@ -38,8 +39,9 @@ def initialize @default_repository_root = default_repository_root @cache = cache + @monitor = Monitor.new - configurations = component_ids.map { |component_id| configurations(configuration(component_id)) }.flatten + configurations = component_ids.map { |component_id| component_configuration(component_id) }.flatten uris(configurations).each { |uri| multitask PACKAGE_NAME => [cache_task(uri)] } end @@ -100,7 +102,7 @@ def cache def cache_task(uri) task uri do |t| - rake_output_message "Caching #{t.name}" + @monitor.synchronize { rake_output_message "Caching #{t.name}" } cache.get(t.name) {} end @@ -115,18 +117,24 @@ def configuration(id) JavaBuildpack::Util::ConfigurationUtils.load id, false end - def configurations(configuration) + def configurations(component_id, configuration, sub_component_id = nil) configurations = [] if repository_configuration?(configuration) + configuration['component_id'] = component_id + configuration['sub_component_id'] = sub_component_id if sub_component_id configurations << configuration else - configuration.values.each { |v| configurations << configurations(v) if v.is_a? Hash } + configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } end configurations end + def component_configuration(component_id) + configurations(component_id, configuration(component_id)) + end + def default_repository_root configuration('repository')['default_repository_root'].chomp('/') end @@ -150,7 +158,6 @@ def uris(configurations) configurations.each do |configuration| index_configuration(configuration).each do |index_configuration| multitask PACKAGE_NAME => [cache_task(index_configuration[:uri])] - get_from_cache(configuration, index_configuration, uris) end end @@ -162,6 +169,7 @@ def get_from_cache(configuration, index_configuration, uris) @cache.get(index_configuration[:uri]) do |f| index = YAML.load f found_version = version(configuration, index) + pin_version(configuration, found_version.to_s) if ENV['PINNED'].to_b if found_version.nil? rake_output_message "Unable to resolve version '#{configuration['version']}' for platform " \ @@ -172,6 +180,25 @@ def get_from_cache(configuration, index_configuration, uris) end end + def pin_version(old_configuration, version) + component_id = old_configuration['component_id'] + sub_component_id = old_configuration['sub_component_id'] + rake_output_message "Pinning #{sub_component_id ? sub_component_id : component_id} version to #{version}" + configuration_to_update = JavaBuildpack::Util::ConfigurationUtils.load(component_id, true) + update_configuration(configuration_to_update, version, sub_component_id) + JavaBuildpack::Util::ConfigurationUtils.write(component_id, configuration_to_update, true) + end + + def update_configuration(config, version, sub_component) + if sub_component.nil? + config['version'] = version + elsif config.key?(sub_component) + config[sub_component]['version'] = version + else + config.values.each { |v| update_configuration(v, version, sub_component) if v.is_a? Hash } + end + end + def version(configuration, index) JavaBuildpack::Repository::VersionResolver.resolve( JavaBuildpack::Util::TokenizedVersion.new(configuration['version']), index.keys) diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 4435bb088c..f57d940a2a 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -16,6 +16,7 @@ require 'java_buildpack/util' require 'java_buildpack/util/configuration_utils' +require 'fileutils' require 'logging_helper' require 'pathname' require 'spec_helper' @@ -24,24 +25,32 @@ describe JavaBuildpack::Util::ConfigurationUtils do include_context 'logging_helper' + let(:test_data) do + { 'foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.7.1' } + end + it 'not load absent configuration file' do allow_any_instance_of(Pathname).to receive(:exist?).and_return(false) expect(described_class.load('test')).to eq({}) end + it 'write configuration file' do + described_class.write('test', test_data) + expect(described_class.load('test')).to eq(test_data) + Pathname.new(File.expand_path('../../../config/test.yml', File.dirname(__FILE__))).delete + end + context do before do allow_any_instance_of(Pathname).to receive(:exist?).and_return(true) - allow(YAML).to receive(:load_file).and_return('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, - 'version' => '1.7.1') + allow(YAML).to receive(:load_file).and_return(test_data) end it 'load configuration file' do - expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, - 'version' => '1.7.1') + expect(described_class.load('test')).to eq(test_data) end context do From 1f04bd9d0b90665780e5d80825e9f532906b6624 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 23 Jun 2015 15:28:38 +0100 Subject: [PATCH 051/812] Pin versions in the offline buildpack This commit fixes a broken test for the previous commit along with some formatting issues. [#93987158] --- .../util/configuration_utils.rb | 4 +--- .../util/configuration_utils_spec.rb | 21 ++++++++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index e493b11422..195cb01876 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -64,7 +64,7 @@ def write(identifier, new_content, should_log = true) header = header(file) File.open(file, 'w') do |f| - header.each { |line| f.write line} + header.each { |line| f.write line } # f.write(header.join('\n')) # f.write('\n') YAML.dump(new_content, f) @@ -72,10 +72,8 @@ def write(identifier, new_content, should_log = true) else logger.debug { "No configuration file #{file} found" } if should_log end - end - private CONFIG_DIRECTORY = Pathname.new(File.expand_path('../../../config', File.dirname(__FILE__))).freeze diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index f57d940a2a..2a2c6270d4 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -37,9 +37,12 @@ end it 'write configuration file' do - described_class.write('test', test_data) - expect(described_class.load('test')).to eq(test_data) - Pathname.new(File.expand_path('../../../config/test.yml', File.dirname(__FILE__))).delete + test_file = Pathname.new(File.expand_path('../../../config/tomcat.yml', File.dirname(__FILE__))) + original_content = file_contents test_file + loaded_content = described_class.load('tomcat') + described_class.write('tomcat', loaded_content) + expect(described_class.load('tomcat')).to eq(loaded_content) + expect(file_contents test_file).to eq(original_content) end context do @@ -96,4 +99,16 @@ end + private + + def file_contents(file) + header = [] + File.open(file, 'r') do |f| + f.each do |line| + header << line + end + end + header + end + end From c17a1e060d25c67a9ce20bc6934bd8405e678a9c Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 23 Jun 2015 15:39:08 +0100 Subject: [PATCH 052/812] Revert mutative change from upstream repo A previous commit contained a change that would of a required a mutative delta in downstream repos. This commit removes that change so that downstream repos can remain purely additive. [#93987158] --- spec/java_buildpack/util/configuration_utils_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 2a2c6270d4..68afb8eac8 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -37,11 +37,11 @@ end it 'write configuration file' do - test_file = Pathname.new(File.expand_path('../../../config/tomcat.yml', File.dirname(__FILE__))) + test_file = Pathname.new(File.expand_path('../../../config/open_jdk_jre.yml', File.dirname(__FILE__))) original_content = file_contents test_file - loaded_content = described_class.load('tomcat') - described_class.write('tomcat', loaded_content) - expect(described_class.load('tomcat')).to eq(loaded_content) + loaded_content = described_class.load('open_jdk_jre') + described_class.write('open_jdk_jre', loaded_content) + expect(described_class.load('open_jdk_jre')).to eq(loaded_content) expect(file_contents test_file).to eq(original_content) end From 7a538fb5f0611237643c38eb1bfaafbba825d502 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 23 Jun 2015 16:39:01 +0100 Subject: [PATCH 053/812] More lenient YAML testing Ruby before and after 2.0 formats YAML differently. This commit makes a test more lenient of this difference so that CI builds on Ruby 2.2.2 pass. [#93987158] --- lib/java_buildpack/util/configuration_utils.rb | 2 -- spec/java_buildpack/util/configuration_utils_spec.rb | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 195cb01876..289d199cd6 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -65,8 +65,6 @@ def write(identifier, new_content, should_log = true) File.open(file, 'w') do |f| header.each { |line| f.write line } - # f.write(header.join('\n')) - # f.write('\n') YAML.dump(new_content, f) end else diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 68afb8eac8..5b10b80312 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -105,6 +105,7 @@ def file_contents(file) header = [] File.open(file, 'r') do |f| f.each do |line| + break if line =~ /^---/ header << line end end From ce37f5ec0fe6d7c977326869b5605011c160ddae Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 8 Jul 2015 16:23:10 +0100 Subject: [PATCH 054/812] Provide extra configuration to New Relic This commit allows additional configuration values to be specified on New Relic through the Credentials payload of the bound New Relic service. This also includes the ability to provide an application name in place of the default provided by Cloud Foundry. All configuration names follow those defined by New Relic. [#92119348] [resolves #173] --- docs/framework-new_relic_agent.md | 4 +- .../framework/new_relic_agent.rb | 45 ++++++++++++------- .../framework/new_relic_agent_spec.rb | 18 +++++++- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/docs/framework-new_relic_agent.md b/docs/framework-new_relic_agent.md index 815781cd70..9caf545bf0 100644 --- a/docs/framework-new_relic_agent.md +++ b/docs/framework-new_relic_agent.md @@ -23,7 +23,9 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- -| `licenseKey` | The license key to use when authenticating +| `license_key` | (Optional) Either this credential or `licenseKey` must be provided. If both are provided then the value for `license_key` will always win. The license key to use when authenticating. +| `licenseKey` | (Optional) As above. +| `***` | (Optional) Any additional entries will be applied as a system property appended to `-Dnewrelic.config.` to allow full configuration of the agent. ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index c02a46576c..ce0854f306 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -26,45 +26,58 @@ class NewRelicAgent < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile - FileUtils.mkdir_p logs_dir download_jar @droplet.copy_resources end # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.java_opts - .add_javaagent(@droplet.sandbox + jar_name) - .add_system_property('newrelic.home', @droplet.sandbox) - .add_system_property('newrelic.config.license_key', license_key) - .add_system_property('newrelic.config.app_name', "#{application_name}") - .add_system_property('newrelic.config.log_file_path', logs_dir) - @droplet.java_opts.add_system_property('newrelic.enable.java.8', 'true') if @droplet.java_home.java_8_or_later? + credentials = @application.services.find_service(FILTER)['credentials'] + java_opts = @droplet.java_opts + configuration = {} + + apply_configuration(credentials, configuration) + apply_user_configuration(credentials, configuration) + write_java_opts(java_opts, configuration) + + java_opts.add_javaagent(@droplet.sandbox + jar_name) + .add_system_property('newrelic.home', @droplet.sandbox) + java_opts.add_system_property('newrelic.enable.java.8', 'true') if @droplet.java_home.java_8_or_later? end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, 'licenseKey' + @application.services.one_service? FILTER, [LICENSE_KEY, LICENSE_KEY_USER] end private FILTER = /newrelic/.freeze - private_constant :FILTER + LICENSE_KEY = 'licenseKey'.freeze + + LICENSE_KEY_USER = 'license_key'.freeze + + private_constant :FILTER, :LICENSE_KEY, :LICENSE_KEY_USER - def application_name - @application.details['application_name'] + def apply_configuration(credentials, configuration) + configuration['log_file_name'] = 'STDOUT' + configuration[LICENSE_KEY_USER] = credentials[LICENSE_KEY] + configuration['app_name'] = @application.details['application_name'] end - def license_key - @application.services.find_service(FILTER)['credentials']['licenseKey'] + def apply_user_configuration(credentials, configuration) + credentials.each do |key, value| + configuration[key] = value + end end - def logs_dir - @droplet.sandbox + 'logs' + def write_java_opts(java_opts, configuration) + configuration.each do |key, value| + java_opts.add_system_property("newrelic.config.#{key}", value) + end end end diff --git a/spec/java_buildpack/framework/new_relic_agent_spec.rb b/spec/java_buildpack/framework/new_relic_agent_spec.rb index 5d188eb0d1..519c6a8db2 100644 --- a/spec/java_buildpack/framework/new_relic_agent_spec.rb +++ b/spec/java_buildpack/framework/new_relic_agent_spec.rb @@ -29,7 +29,7 @@ context do before do - allow(services).to receive(:one_service?).with(/newrelic/, 'licenseKey').and_return(true) + allow(services).to receive(:one_service?).with(/newrelic/, %w(licenseKey license_key)).and_return(true) end it 'detects with newrelic-n/a service' do @@ -62,7 +62,21 @@ expect(java_opts).to include('-Dnewrelic.home=$PWD/.java-buildpack/new_relic_agent') expect(java_opts).to include('-Dnewrelic.config.license_key=test-license-key') expect(java_opts).to include('-Dnewrelic.config.app_name=test-application-name') - expect(java_opts).to include('-Dnewrelic.config.log_file_path=$PWD/.java-buildpack/new_relic_agent/logs') + expect(java_opts).to include('-Dnewrelic.config.log_file_name=STDOUT') + end + + it 'updates JAVA_OPTS with additional options' do + allow(services).to receive(:find_service).and_return('credentials' => { 'licenseKey' => 'test-license-key', + 'license_key' => 'different-license-key', + 'app_name' => 'different-name', + 'foo' => 'bar' }) + allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.7.0_u10')) + + component.release + + expect(java_opts).to include('-Dnewrelic.config.license_key=different-license-key') + expect(java_opts).to include('-Dnewrelic.config.app_name=different-name') + expect(java_opts).to include('-Dnewrelic.config.foo=bar') end it 'updates JAVA_OPTS on Java 8' do From 0fd42baae6eed1576002ad365c66e4d4a7ffde28 Mon Sep 17 00:00:00 2001 From: Josef Hoerandtner Date: Wed, 15 Jul 2015 08:09:32 +0100 Subject: [PATCH 055/812] Fixed resources section of dynatrace documentation The resource section seems to be copied from another framework: - fix naming - remove profile example since it does not apply to dynatrace --- docs/framework-dyna_trace_agent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-dyna_trace_agent.md b/docs/framework-dyna_trace_agent.md index d6bcc678a5..f6603a9028 100644 --- a/docs/framework-dyna_trace_agent.md +++ b/docs/framework-dyna_trace_agent.md @@ -68,7 +68,7 @@ The framework can be configured by modifying the [`config/dyna_trace_agent.yml`] | `version` | The version of DynaTrace to use. This buildpack framework has been tested on 6.1.0. ### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/ca_wily_agent` directory in the buildpack fork. For example, to override the default profile add your custom profile to `resources/introscope_agent/`. +The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/dyna_trace_agent` directory in the buildpack fork. [Configuration and Extension]: ../README.md#configuration-and-extension [`config/dyna_trace_agent.yml`]: ../config/dyna_trace_agent.yml From 309e8c5e507ef8eed50dfb8ca79c62f9060a16ea Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 22 Jul 2015 16:00:40 +0100 Subject: [PATCH 056/812] Support nil configuration values This commit makes a number of changes all required to support `nil` or empty values in the configuration files. Any `key` with a `nil` value will be ignored but as it is present it can be modified with a new value via an environment variable. Aditional changes ensure offline buildpacks still contain `nil` configuration values after version pinning. Updates the Java Opts suppport to have a `nil` `java_opts` configuration. Add in some additional `nil` configuration for the memory calculator so these can also be updated via environment variables. closes #202 and closes #204 [#98822486] --- README.md | 2 +- config/java_opts.yml | 2 +- config/open_jdk_jre.yml | 5 +++- config/oracle_jre.yml | 11 ++++--- docs/jre-open_jdk_jre.md | 14 +++++---- docs/jre-oracle_jre.md | 12 ++++---- lib/java_buildpack/buildpack_version.rb | 2 +- lib/java_buildpack/framework/java_opts.rb | 2 +- lib/java_buildpack/logging/logger_factory.rb | 3 +- .../util/configuration_utils.rb | 24 +++++++++++---- rakelib/dependency_cache_task.rb | 6 ++-- spec/java_buildpack/buildpack_version_spec.rb | 3 +- .../framework/java_opts_spec.rb | 8 +++++ .../logging/logger_factory_spec.rb | 4 +-- .../util/configuration_utils_spec.rb | 30 ++++++++++++------- 15 files changed, 84 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index feeb25e82e..53cdfd24ac 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The following are _very_ simple examples for deploying the artifact types that w ## Configuration and Extension The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. -Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. The value of the variable should be valid inline yaml. For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. +Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml. For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. ```cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '[jre: {version: 1.7.0_+}, memory_calculator: {memory_heuristics: {heap: 85, stack: 10}}]'``` diff --git a/config/java_opts.yml b/config/java_opts.yml index 92faa2e361..41da9b3a21 100644 --- a/config/java_opts.yml +++ b/config/java_opts.yml @@ -16,4 +16,4 @@ # JAVA_OPTS configuration --- from_environment: true -# java_opts: +java_opts: diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index b901310268..1f39ee6ab6 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -23,11 +23,14 @@ memory_calculator: version: 1.+ repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' memory_sizes: + heap: metaspace: 64m.. + native: permgen: 64m.. + stack: memory_heuristics: heap: 75 metaspace: 10 + native: 10 permgen: 10 stack: 5 - native: 10 diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index d7591ad095..34627cc60e 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -15,22 +15,25 @@ # Configuration for JRE repositories keyed by vendor # Pre Java 1.8, permgen was used instead of metaspace. Please see the documentation for more detail. ---- + # You must specify a the repository root of an Oracle JRE repository. Please see the documentation for more detail. # e.g. repository_root: "http://example.com/oracle-jre/{platform}/{architecture}" - +--- jre: version: 1.8.0_+ repository_root: "" memory_calculator: version: 1.+ - repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' memory_sizes: + heap: metaspace: 64m.. + native: permgen: 64m.. + stack: memory_heuristics: heap: 75 metaspace: 10 + native: 10 permgen: 10 stack: 5 - native: 10 diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index ecb3c72ad8..28f9bddc7b 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -26,7 +26,7 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | `version` | The version of Java runtime to use. Candidate versions can be found in the listings for [centos6][], [lucid][], [mountainlion][], and [precise][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. ### Additional Resources -The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/open_jdk_jre` directory in the buildpack fork. For example, to add the JCE Unlimited Strength `local_policy.jar` add your file to `resources/open_jdk_jre/lib/security/local_policy.jar`. +The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/open_jdk_jre` directory in the buildpack fork. For example, to add the JCE Unlimited Strength `local_policy.jar` add your file to `resources/open_jdk_jre/lib/security/local_policy.jar`. ### Memory The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes` and/or `memory_heuristics` mappings. @@ -48,7 +48,7 @@ Memory sizes together with _memory weightings_ (described in the next section) a Memory sizes consist of a non-negative integer followed by a unit (`k` for kilobytes, `m` for megabytes, `g` for gigabytes; the case is not significant). Only the memory size `0` may be specified without a unit. -The above memory size properties may be omitted, specified as a single value, or specified as a range. Ranges use the syntax `..`, although either bound may be omitted in which case the defaults of zero and the total available memory are used for the lower bound and upper bound, respectively. Examples of ranges are `100m..200m` (any value between 100 and 200 megabytes, inclusive) and `100m..` (any value greater than or equal to 100 megabytes). +The above memory size properties may be omitted with an empty value, specified as a single value, or specified as a range. Ranges use the syntax `..`, although either bound may be omitted in which case the defaults of zero and the total available memory are used for the lower bound and upper bound, respectively. Examples of ranges are `100m..200m` (any value between 100 and 200 megabytes, inclusive) and `100m..` (any value greater than or equal to 100 megabytes). Each form of memory size is equivalent to a range. Omitting a memory size is equivalent to specifying the range `0..`. Specifying a single value is equivalent to specifying the range with that value as both the lower and upper bound, for example `128m` is equivalent to the range `128m..128m`. @@ -58,9 +58,9 @@ Memory weightings are configured in the `memory_heuristics` mapping of [`config/ ```yaml memory_heuristics: heap: 15 + native: 2 permgen: 5 stack: 1 - native: 2 ``` represent a maximum heap size three times as large as the maximum PermGen size, and so on. @@ -68,16 +68,18 @@ represent a maximum heap size three times as large as the maximum PermGen size, Memory weightings are used together with memory ranges to calculate the amount of memory for each memory type, as follows. #### Memory Calculation -The total available memory is allocated into heap, Metaspace or PermGen (depending on the version of OpenJDK), stack, and native memory types. +Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. + +The total available memory is allocated into heap, Metaspace or PermGen (depending on the version of Oracle), stack, and native memory types. -The total available memory is allocated to each memory type in proportion to its weighting. If the resultant size of a memory type lies outside its range, the size is constrained to -the range, the constrained size is excluded from the remaining memory, and no further calculation is required for the memory type. If the resultant size of a memory size lies within its range, the size is included in the remaining memory. The remaining memory is then allocated to the remaining memory types in a similar fashion. Allocation terminates when none of the sizes of the remaining memory types is constrained by the corresponding range. +The total available memory is first allocated to each memory type in proportion to its weighting (this is called ‘balancing'). If the resultant size of any memory type lies outside its range, the size is constrained to the range, the constrained size is excluded from the remaining memory, and no further calculation is required for that memory type. The remaining memory is then balanced against the memory types that are left, and the check is repeated until no calculated memory sizes lie outside their ranges. The remaining memory is then allocated to the remaining memory types according to the last balance step. This iteration terminates when none of the sizes of the remaining memory types is constrained by their corresponding ranges. Termination is guaranteed since there is a finite number of memory types and in each iteration either none of the remaining memory sizes is constrained by the corresponding range and allocation terminates or at least one memory size is constrained by the corresponding range and is omitted from the next iteration. [`config/open_jdk_jre.yml`]: ../config/open_jdk_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [centos6]: http://download.pivotal.io.s3.amazonaws.com/openjdk/centos6/x86_64/index.yml +[Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [lucid]: http://download.pivotal.io.s3.amazonaws.com/openjdk/lucid/x86_64/index.yml [mountainlion]: http://download.pivotal.io.s3.amazonaws.com/openjdk/mountainlion/x86_64/index.yml [OpenJDK]: http://openjdk.java.net diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 1b5612eb29..858928b2fb 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -35,7 +35,7 @@ The JRE can be configured by modifying the [`config/oracle_jre.yml`][] file in t | `version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. ### Additional Resources -The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/oracle_jre` directory in the buildpack fork. For example, to add the JCE Unlimited Strength `local_policy.jar` add your file to `resources/oracle_jre/lib/security/local_policy.jar`. +The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/oracle_jre` directory in the buildpack fork. For example, to add the JCE Unlimited Strength `local_policy.jar` add your file to `resources/oracle_jre/lib/security/local_policy.jar`. ### Memory The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes` and/or `memory_heuristics` mappings. @@ -57,7 +57,7 @@ Memory sizes together with _memory weightings_ (described in the next section) a Memory sizes consist of a non-negative integer followed by a unit (`k` for kilobytes, `m` for megabytes, `g` for gigabytes; the case is not significant). Only the memory size `0` may be specified without a unit. -The above memory size properties may be omitted, specified as a single value, or specified as a range. Ranges use the syntax `..`, although either bound may be omitted in which case the defaults of zero and the total available memory are used for the lower bound and upper bound, respectively. Examples of ranges are `100m..200m` (any value between 100 and 200 megabytes, inclusive) and `100m..` (any value greater than or equal to 100 megabytes). +The above memory size properties may be omitted with an empty value, specified as a single value, or specified as a range. Ranges use the syntax `..`, although either bound may be omitted in which case the defaults of zero and the total available memory are used for the lower bound and upper bound, respectively. Examples of ranges are `100m..200m` (any value between 100 and 200 megabytes, inclusive) and `100m..` (any value greater than or equal to 100 megabytes). Each form of memory size is equivalent to a range. Omitting a memory size is equivalent to specifying the range `0..`. Specifying a single value is equivalent to specifying the range with that value as both the lower and upper bound, for example `128m` is equivalent to the range `128m..128m`. @@ -67,9 +67,9 @@ Memory weightings are configured in the `memory_heuristics` mapping of [`config/ ```yaml memory_heuristics: heap: 15 + native: 2 permgen: 5 stack: 1 - native: 2 ``` represent a maximum heap size three times as large as the maximum PermGen size, and so on. @@ -77,16 +77,18 @@ represent a maximum heap size three times as large as the maximum PermGen size, Memory weightings are used together with memory ranges to calculate the amount of memory for each memory type, as follows. #### Memory Calculation +Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. + The total available memory is allocated into heap, Metaspace or PermGen (depending on the version of Oracle), stack, and native memory types. -The total available memory is allocated to each memory type in proportion to its weighting. If the resultant size of a memory type lies outside its range, the size is constrained to -the range, the constrained size is excluded from the remaining memory, and no further calculation is required for the memory type. If the resultant size of a memory size lies within its range, the size is included in the remaining memory. The remaining memory is then allocated to the remaining memory types in a similar fashion. Allocation terminates when none of the sizes of the remaining memory types is constrained by the corresponding range. +The total available memory is first allocated to each memory type in proportion to its weighting (this is called ‘balancing'). If the resultant size of any memory type lies outside its range, the size is constrained to the range, the constrained size is excluded from the remaining memory, and no further calculation is required for that memory type. The remaining memory is then balanced against the memory types that are left, and the check is repeated until no calculated memory sizes lie outside their ranges. The remaining memory is then allocated to the remaining memory types according to the last balance step. This iteration terminates when none of the sizes of the remaining memory types is constrained by their corresponding ranges. Termination is guaranteed since there is a finite number of memory types and in each iteration either none of the remaining memory sizes is constrained by the corresponding range and allocation terminates or at least one memory size is constrained by the corresponding range and is omitted from the next iteration. [`config/components.yml`]: ../config/components.yml [`config/oracle_jre.yml`]: ../config/oracle_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension +[Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [OpenJDK JRE]: jre-open_jdk_jre.md [Oracle]: http://www.oracle.com/technetwork/java/index.html [repositories]: extending-repositories.md diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index 4a9017de37..4429863a26 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -45,7 +45,7 @@ class BuildpackVersion # Creates a new instance def initialize(should_log = true) - configuration = JavaBuildpack::Util::ConfigurationUtils.load 'version', should_log + configuration = JavaBuildpack::Util::ConfigurationUtils.load('version', true, should_log) @hash = configuration['hash'] || hash @offline = configuration['offline'] || ENV['OFFLINE'].to_b @remote = configuration['remote'] || remote diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index 568313fbea..6140635b05 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -75,7 +75,7 @@ def parsed_java_opts end def supports_configuration? - @configuration.key? CONFIGURATION_PROPERTY + @configuration.key?(CONFIGURATION_PROPERTY) && !@configuration[CONFIGURATION_PROPERTY].nil? end def supports_environment? diff --git a/lib/java_buildpack/logging/logger_factory.rb b/lib/java_buildpack/logging/logger_factory.rb index 405b0add76..37984fde14 100644 --- a/lib/java_buildpack/logging/logger_factory.rb +++ b/lib/java_buildpack/logging/logger_factory.rb @@ -129,7 +129,8 @@ def ruby_mode def severity severity = ENV['JBP_LOG_LEVEL'] severity = ruby_mode unless severity - severity = JavaBuildpack::Util::ConfigurationUtils.load('logging', false)['default_log_level'] unless severity + severity = + JavaBuildpack::Util::ConfigurationUtils.load('logging', true, false)['default_log_level'] unless severity severity = 'INFO' unless severity "::Logger::Severity::#{severity.upcase}".constantize diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 289d199cd6..cbd8da87d6 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -35,15 +35,17 @@ class << self # configuration, if present. Will not add a new configuration key where an existing one does not exist. # # @param [String] identifier the identifier of the configuration to load + # @param [Boolean] clean_nil_values whether empty/nil values should be removed along with their keys from the + # returned configuration. # @param [Boolean] should_log whether the contents of the configuration file should be logged. This value # should be left to its default and exists to allow the logger to use the utility. # @return [Hash] the configuration or an empty hash if the configuration file does not exist - def load(identifier, should_log = true) + def load(identifier, clean_nil_values = true, should_log = true) file = file_name(identifier) if file.exist? user_provided = ENV[environment_variable_name(identifier)] - configuration = load_configuration(file, user_provided, should_log) + configuration = load_configuration(file, user_provided, clean_nil_values, should_log) else logger.debug { "No configuration file #{file} found" } if should_log end @@ -80,6 +82,17 @@ def write(identifier, new_content, should_log = true) private_constant :CONFIG_DIRECTORY, :ENVIRONMENT_VARIABLE_PATTERN + def clean_nil_values(configuration) + configuration.each do |key, value| + if value.is_a?(Hash) + configuration[key] = clean_nil_values value + elsif value.nil? + configuration.delete key + end + end + configuration + end + def file_name(identifier) CONFIG_DIRECTORY + "#{identifier}.yml" end @@ -96,7 +109,7 @@ def header(file) header end - def load_configuration(file, user_provided, should_log) + def load_configuration(file, user_provided, clean_nil_values, should_log) configuration = YAML.load_file(file) logger.debug { "Configuration from #{file}: #{configuration}" } if should_log @@ -105,15 +118,14 @@ def load_configuration(file, user_provided, should_log) if user_provided_value.is_a?(Hash) configuration = do_merge(configuration, user_provided_value, should_log) elsif user_provided_value.is_a?(Array) - user_provided_value.each do |new_prop| - configuration = do_merge(configuration, new_prop, should_log) - end + user_provided_value.each { |new_prop| configuration = do_merge(configuration, new_prop, should_log) } else fail "User configuration value is not valid: #{user_provided_value}" end logger.debug { "Configuration from #{file} modified with: #{user_provided}" } if should_log end + clean_nil_values configuration if clean_nil_values configuration end diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 908a82d6df..26d160fcf3 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -114,7 +114,7 @@ def component_ids end def configuration(id) - JavaBuildpack::Util::ConfigurationUtils.load id, false + JavaBuildpack::Util::ConfigurationUtils.load(id, false, false) end def configurations(component_id, configuration, sub_component_id = nil) @@ -184,9 +184,9 @@ def pin_version(old_configuration, version) component_id = old_configuration['component_id'] sub_component_id = old_configuration['sub_component_id'] rake_output_message "Pinning #{sub_component_id ? sub_component_id : component_id} version to #{version}" - configuration_to_update = JavaBuildpack::Util::ConfigurationUtils.load(component_id, true) + configuration_to_update = JavaBuildpack::Util::ConfigurationUtils.load(component_id, false, true) update_configuration(configuration_to_update, version, sub_component_id) - JavaBuildpack::Util::ConfigurationUtils.write(component_id, configuration_to_update, true) + JavaBuildpack::Util::ConfigurationUtils.write(component_id, configuration_to_update) end def update_configuration(config, version, sub_component) diff --git a/spec/java_buildpack/buildpack_version_spec.rb b/spec/java_buildpack/buildpack_version_spec.rb index cd87812e11..9b2a893bd0 100644 --- a/spec/java_buildpack/buildpack_version_spec.rb +++ b/spec/java_buildpack/buildpack_version_spec.rb @@ -28,7 +28,8 @@ before do |example| configuration = example.metadata[:configuration] || {} - allow(JavaBuildpack::Util::ConfigurationUtils).to receive(:load).with('version', true).and_return(configuration) + allow(JavaBuildpack::Util::ConfigurationUtils).to receive(:load).with('version', true, true) + .and_return(configuration) end it 'creates offline version string from config/version.yml', diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index 3232fd6a73..154497adaf 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -46,6 +46,14 @@ end end + context do + let(:configuration) { { 'java_opts' => nil } } + + it 'does not detect with nil java_opts configuration' do + expect(component.detect).to be_nil + end + end + it 'does not detect without java_opts configuration' do expect(component.detect).to be_nil end diff --git a/spec/java_buildpack/logging/logger_factory_spec.rb b/spec/java_buildpack/logging/logger_factory_spec.rb index bb8e513b48..92056a88bd 100644 --- a/spec/java_buildpack/logging/logger_factory_spec.rb +++ b/spec/java_buildpack/logging/logger_factory_spec.rb @@ -183,7 +183,7 @@ context do before do - allow(JavaBuildpack::Util::ConfigurationUtils).to receive(:load).with('logging', false) + allow(JavaBuildpack::Util::ConfigurationUtils).to receive(:load).with('logging', true, false) .and_return('default_log_level' => 'DEBUG') described_class.instance.setup app_dir end @@ -208,7 +208,7 @@ context do before do - allow(JavaBuildpack::Util::ConfigurationUtils).to receive(:load).with('logging', false).and_return({}) + allow(JavaBuildpack::Util::ConfigurationUtils).to receive(:load).with('logging', true, false).and_return({}) described_class.instance.setup app_dir end diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 5b10b80312..bcfaa74175 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -26,9 +26,11 @@ include_context 'logging_helper' let(:test_data) do - { 'foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, - 'version' => '1.7.1' } + { 'foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.7.1', + 'not_here' => nil + } end it 'not load absent configuration file' do @@ -37,11 +39,11 @@ end it 'write configuration file' do - test_file = Pathname.new(File.expand_path('../../../config/open_jdk_jre.yml', File.dirname(__FILE__))) + test_file = Pathname.new(File.expand_path('../../../config/open_jdk_jre.yml', File.dirname(__FILE__))) original_content = file_contents test_file - loaded_content = described_class.load('open_jdk_jre') + loaded_content = described_class.load('open_jdk_jre', false) described_class.write('open_jdk_jre', loaded_content) - expect(described_class.load('open_jdk_jre')).to eq(loaded_content) + expect(described_class.load('open_jdk_jre', false)).to eq(loaded_content) expect(file_contents test_file).to eq(original_content) end @@ -53,7 +55,13 @@ end it 'load configuration file' do - expect(described_class.load('test')).to eq(test_data) + expect(described_class.load('test', false)).to eq(test_data) + end + + it 'load configuration file and clean nil values' do + expect(described_class.load('test', true)).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.7.1') end context do @@ -64,8 +72,8 @@ it 'overlays matching environment variables' do - expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 3, 'two' => 'dog' } }, + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 3, 'two' => 'dog' } }, 'version' => '1.7.1') end @@ -78,8 +86,8 @@ end it 'overlays simple matching environment variable' do - expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, 'version' => '1.8.+') end From 8c3d276a36006bb4476e257d9926986070d28f51 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 28 Jul 2015 10:56:10 +0100 Subject: [PATCH 057/812] Remove Memory Calculate at Staging Note Update the docs to correctly state that memory will be calculated on application start. [#99933632] --- docs/jre-open_jdk_jre.md | 2 +- docs/jre-oracle_jre.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 28f9bddc7b..8e7f5b8293 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -31,7 +31,7 @@ The JRE can also be configured by overlaying a set of resources on the default d ### Memory The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes` and/or `memory_heuristics` mappings. -Note: if the total available memory is scaled up or down, the Java buildpack does not re-calculate the JRE memory settings until the next time the appication is pushed. +Note: if the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the appication is started. #### Memory Sizes The following optional properties may be specified in the `memory_sizes` mapping. diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 858928b2fb..f3877b53f7 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -40,7 +40,7 @@ The JRE can also be configured by overlaying a set of resources on the default d ### Memory The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes` and/or `memory_heuristics` mappings. -Note: if the total available memory is scaled up or down, the Java buildpack does not re-calculate the JRE memory settings until the next time the appication is pushed. +Note: if the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the appication is started. #### Memory Sizes The following optional properties may be specified in the `memory_sizes` mapping. From 9e5b563145cfa43ffb35160a15c4636cc74c3148 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 29 Jul 2015 11:41:40 +0100 Subject: [PATCH 058/812] Add a test for escaped chars in java_opts vars This commit adds a test to prove that escaped chars are handled correctly in the environment variable values of `java_opts`. --- spec/java_buildpack/framework/java_opts_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index 154497adaf..69a326e926 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -86,6 +86,18 @@ end end + context do + let(:configuration) do + { 'java_opts' => '-javaagent:agent.jar=port="\$PORT",host=localhost' } + end + + it 'allows escaped characters' do + component.release + + expect(java_opts).to include('-javaagent:agent.jar=port=$PORT,host=localhost') + end + end + context do let(:configuration) { { 'java_opts' => '-Xms1024M' } } From 453d1f695e40aa8092c774e36cbc1647b67672f1 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 16 Jul 2015 10:40:30 +0100 Subject: [PATCH 059/812] Safenet Luna Security Provider The change adds a framework for the Safenet Luna Security Provider. This framework is triggered by a service with the name 'luna' in it. It depends on that service having the HSM host, host-certificate, client, and client-certificate. In also expects users to provide a repository with the Luna Client binaries in it. [#96530962][#99962452] --- .idea/dictionaries/bhale.xml | 5 + README.md | 1 + config/components.yml | 1 + config/luna_security_provider.yml | 19 +++ docs/framework-luna_security_provider.md | 46 ++++++ java-buildpack.iml | 2 +- lib/java_buildpack/buildpack.rb | 45 +++--- lib/java_buildpack/component/droplet.rb | 19 ++- .../component/environment_variables.rb | 62 ++++++++ lib/java_buildpack/component/java_opts.rb | 2 +- lib/java_buildpack/container/dist_zip_like.rb | 1 + lib/java_buildpack/container/groovy.rb | 1 + lib/java_buildpack/container/java_main.rb | 11 +- lib/java_buildpack/container/spring_boot.rb | 3 +- .../container/spring_boot_cli.rb | 4 +- lib/java_buildpack/container/tomcat.rb | 1 + .../framework/dyna_trace_agent.rb | 1 - .../framework/luna_security_provider.rb | 148 ++++++++++++++++++ lib/java_buildpack/framework/rpm2cpio.py | 85 ++++++++++ .../repository/configured_item.rb | 2 +- lib/java_buildpack/util/play/base.rb | 3 +- .../luna_security_provider/Chrystoki.conf | 32 ++++ .../luna_security_provider/java.security | 1 + spec/droplet_helper.rb | 10 +- spec/fixtures/stub-luna-security-provider.tar | Bin 0 -> 51200 bytes spec/java_buildpack/component/droplet_spec.rb | 4 + .../component/environment_variables_spec.rb | 45 ++++++ .../container/dist_zip_like_spec.rb | 3 +- spec/java_buildpack/container/groovy_spec.rb | 8 +- .../container/java_main_spec.rb | 49 +++--- spec/java_buildpack/container/ratpack_spec.rb | 3 +- .../container/spring_boot_cli_spec.rb | 8 +- .../container/spring_boot_spec.rb | 12 +- spec/java_buildpack/container/tomcat_spec.rb | 4 +- .../framework/luna_security_provider_spec.rb | 106 +++++++++++++ spec/java_buildpack/util/play/post22_spec.rb | 2 +- .../util/play/pre22_dist_spec.rb | 4 +- .../util/play/pre22_staged_spec.rb | 4 +- 38 files changed, 682 insertions(+), 75 deletions(-) create mode 100644 config/luna_security_provider.yml create mode 100644 docs/framework-luna_security_provider.md create mode 100644 lib/java_buildpack/component/environment_variables.rb create mode 100644 lib/java_buildpack/framework/luna_security_provider.rb create mode 100755 lib/java_buildpack/framework/rpm2cpio.py create mode 100644 resources/luna_security_provider/Chrystoki.conf create mode 100644 resources/luna_security_provider/java.security create mode 100644 spec/fixtures/stub-luna-security-provider.tar create mode 100644 spec/java_buildpack/component/environment_variables_spec.rb create mode 100644 spec/java_buildpack/framework/luna_security_provider_spec.rb diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 00373e0290..2a83fa8ef8 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -5,9 +5,11 @@ appdynamics argv atpack + chrystoki codeclimate constantized constantizes + cpio creat dhttp dirname @@ -33,7 +35,9 @@ jsome jtest killjava + libcryptoki ljust + lunaclient mainclass metaspace mkdir @@ -63,6 +67,7 @@ rstrip rubo rubocop + safenet scriptdir shellwords simplecov diff --git a/README.md b/README.md index 53cdfd24ac..0122e7e46c 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [DynaTrace Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) + * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 811a9147d0..4b30dc02b2 100644 --- a/config/components.yml +++ b/config/components.yml @@ -37,6 +37,7 @@ frameworks: # - "JavaBuildpack::Framework::DynaTraceAgent" - "JavaBuildpack::Framework::JavaOpts" - "JavaBuildpack::Framework::JrebelAgent" +# - "JavaBuildpack::Framework::LunaSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration" diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml new file mode 100644 index 0000000000..4c6b4f4aa1 --- /dev/null +++ b/config/luna_security_provider.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright (c) 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Dynatrace framework +--- +version: 5.3.+ +repository_root: "" diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md new file mode 100644 index 0000000000..da0a6aa845 --- /dev/null +++ b/docs/framework-luna_security_provider.md @@ -0,0 +1,46 @@ +# Luna Security Provider Framework +The Luna Security Provider Framework causes an application to be automatically configured to work with a bound [Luna Security Service][]. **Note:** This framework is disabled by default. + +
+ + + + + + + + +
Detection CriterionExistence of a single bound Luna Security Provider service. The existence of an Luna Security service defined by the VCAP_SERVICES payload containing a service name, label or tag with luna as a substring. +
Tagsluna-security-provider=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +When binding to the Luna Security Provider using a user-provided service, it must have name or tag with `luna` in it. The credential payload can contain the following entries: + +| Name | Description +| ---- | ----------- +| `host` | The controller host name +| `host-certificate` | A PEM encoded host certificate +| `client-private-key` | A PEM encoded client private key +| `client-certificate` | A PEM encoded client certificate + +To provide more complex values such as the PEM certificates, using the interactive mode when creating a user-provided service will manage the character escaping automatically. + +## Configuration +For general information on configuring the buildpack, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/luna_security_provider.yml`][] file in the buildpack. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Luna Security Provider repository index ([details][repositories]). +| `version` | Version of the Luna Security Provider to use. + +### Additional Resources +The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/luna_security_provider` directory in the buildpack fork. + +[`config/luna_security_provider.yml`]: ../config/luna_security_provider.yml +[Luna Security Service]: http://www.safenet-inc.com/data-encryption/hardware-security-modules-hsms/ +[Configuration and Extension]: ../README.md#configuration-and-extension +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/java-buildpack.iml b/java-buildpack.iml index 7aff0361b0..33ec999a40 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -271,7 +271,7 @@ - + diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 84ee132ed5..d02c8fd4dd 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -19,6 +19,7 @@ require 'java_buildpack/component/additional_libraries' require 'java_buildpack/component/application' require 'java_buildpack/component/droplet' +require 'java_buildpack/component/environment_variables' require 'java_buildpack/component/immutable_java_home' require 'java_buildpack/component/java_opts' require 'java_buildpack/component/mutable_java_home' @@ -104,24 +105,26 @@ def initialize(app_dir, application) log_environment_variables - additional_libraries = Component::AdditionalLibraries.new app_dir - mutable_java_home = Component::MutableJavaHome.new - immutable_java_home = Component::ImmutableJavaHome.new mutable_java_home, app_dir - java_opts = Component::JavaOpts.new app_dir + mutable_java_home = Component::MutableJavaHome.new + immutable_java_home = Component::ImmutableJavaHome.new mutable_java_home, app_dir - instantiate_components(additional_libraries, app_dir, application, immutable_java_home, java_opts, - mutable_java_home) + component_info = { + 'additional_libraries' => Component::AdditionalLibraries.new(app_dir), + 'application' => application, + 'env_vars' => Component::EnvironmentVariables.new(app_dir), + 'java_opts' => Component::JavaOpts.new(app_dir), + 'app_dir' => app_dir + } + + instantiate_components(mutable_java_home, immutable_java_home, component_info) end - def instantiate_components(additional_libraries, app_dir, application, immutable_java_home, java_opts, - mutable_java_home) - components = JavaBuildpack::Util::ConfigurationUtils.load 'components' - @jres = instantiate(components['jres'], additional_libraries, application, mutable_java_home, java_opts, - app_dir) - @frameworks = instantiate(components['frameworks'], additional_libraries, application, immutable_java_home, - java_opts, app_dir) - @containers = instantiate(components['containers'], additional_libraries, application, immutable_java_home, - java_opts, app_dir) + def instantiate_components(mutable_java_home, immutable_java_home, component_info) + components = JavaBuildpack::Util::ConfigurationUtils.load 'components' + + @jres = instantiate(components['jres'], mutable_java_home, component_info) + @frameworks = instantiate(components['frameworks'], immutable_java_home, component_info) + @containers = instantiate(components['containers'], immutable_java_home, component_info) end def component_detection(type, components, unique) @@ -146,19 +149,21 @@ def detection(type, components, unique) [detected, tags] end - def instantiate(components, additional_libraries, application, java_home, java_opts, root) + def instantiate(components, java_home, component_info) components.map do |component| @logger.debug { "Instantiating #{component}" } require_component(component) component_id = component.split('::').last.snake_case - context = { - application: application, + + context = { + application: component_info['application'], configuration: Util::ConfigurationUtils.load(component_id), - droplet: Component::Droplet.new(additional_libraries, component_id, java_home, java_opts, root) + droplet: Component::Droplet.new(component_info['additional_libraries'], component_id, + component_info['env_vars'], java_home, + component_info['java_opts'], component_info['app_dir']) } - component.constantize.new(context) end end diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index 0c594b9350..a3a74d491a 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -38,6 +38,10 @@ class Droplet # @return [String] the id of component using this droplet attr_reader :component_id + # @!attribute [r] environment_variables + # @return [EnvironmentVariables] the shared +EnvironmentVariables+ instance for all components + attr_reader :environment_variables + # @!attribute [r] java_home # @return [ImmutableJavaHome, MutableJavaHome] the shared +JavaHome+ instance for all components. If the # component using this instance is a jre, then this will be an @@ -63,18 +67,21 @@ class Droplet # @param [AdditionalLibraries] additional_libraries the shared +AdditionalLibraries+ instance for all # components # @param [String] component_id the id of the component that will use this +Droplet+ + # @param [EnvironmentVariables] env_vars the shared +EnvironmentVariables+ instance for all + # components # @param [ImmutableJavaHome, MutableJavaHome] java_home the shared +JavaHome+ instance for all components. If the # component using this instance is a jre, then this should # be an instance of +MutableJavaHome+. Otherwise it should # be an instance of +ImmutableJavaHome+. # @param [JavaOpts] java_opts the shared +JavaOpts+ instance for all components # @param [Pathname] root the root of the droplet - def initialize(additional_libraries, component_id, java_home, java_opts, root) - @additional_libraries = additional_libraries - @component_id = component_id - @java_home = java_home - @java_opts = java_opts - @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger Droplet + def initialize(additional_libraries, component_id, env_vars, java_home, java_opts, root) + @additional_libraries = additional_libraries + @component_id = component_id + @environment_variables = env_vars + @java_home = java_home + @java_opts = java_opts + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger Droplet buildpack_root = root + '.java-buildpack' sandbox_root = buildpack_root + component_id diff --git a/lib/java_buildpack/component/environment_variables.rb b/lib/java_buildpack/component/environment_variables.rb new file mode 100644 index 0000000000..a10a28e712 --- /dev/null +++ b/lib/java_buildpack/component/environment_variables.rb @@ -0,0 +1,62 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component' +require 'java_buildpack/util/qualify_path' + +module JavaBuildpack + module Component + + # An abstraction encapsulating the Environment Variables of an application. + # + # A new instance of this type should be created once for the application. + class EnvironmentVariables < Array + include JavaBuildpack::Util + + # Creates an instance of the Environment Variables abstraction. + # + # @param [Pathname] droplet_root the root directory of the droplet + def initialize(droplet_root) + @droplet_root = droplet_root + end + + # Adds an environment variable. Prepends +$PWD+ to any variable values that are + # paths (relative to the droplet root) to ensure that the path is always accurate. + # + # @param [String] key the variable name + # @param [String] value the variable value + # @return [EnvironmentVariables] +self+ for chaining + def add_environment_variable(key, value) + self << "#{key}=#{qualify_value(value)}" + end + + # Returns the contents as an environment variable formatted as +=+ + # + # @return [String] the contents as an environment variable + def as_env_vars + join(' ') + end + + private + + def qualify_value(value) + value.respond_to?(:relative_path_from) ? qualify_path(value) : value + end + + end + + end +end diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index 035329c1f8..555763a2d2 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -46,7 +46,7 @@ def add_javaagent(path) # ensure that the path is always accurate. # # @param [Pathname] path the path to the +agentpath+ shared library - # @param [Properties] properties to append to the agentpath entry + # @param [Properties] props to append to the agentpath entry # @return [JavaOpts] +self+ for chaining def add_agentpath_with_props(path, props) add_preformatted_options "-agentpath:#{qualify_path path}=" + props.map { |k, v| "#{k}=#{v}" }.join(',') diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index ba695db434..afca3b5d69 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -41,6 +41,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release [ + @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, @droplet.java_opts.as_env_var, qualify_path(start_script(root), @droplet.root) diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index 9e16c6050e..1991094087 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -53,6 +53,7 @@ def release add_libs [ + @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, @droplet.java_opts.as_env_var, qualify_path(@droplet.sandbox + 'bin/groovy', @droplet.root), diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index 799ecce891..c2f3de5c23 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -42,6 +42,7 @@ def compile def release @droplet.additional_libraries.insert 0, @application.root manifest_class_path.each { |path| @droplet.additional_libraries << path } + @droplet.environment_variables.add_environment_variable 'SERVER_PORT', '$PORT' if boot_launcher? release_text end @@ -56,7 +57,7 @@ def release def release_text [ - port, + @droplet.environment_variables.as_env_vars, "#{qualify_path @droplet.java_home.root, @droplet.root}/bin/java", @droplet.additional_libraries.as_classpath, @droplet.java_opts.join(' '), @@ -69,6 +70,10 @@ def arguments @configuration[ARGUMENTS_PROPERTY] end + def boot_launcher? + main_class =~ /^org\.springframework\.boot\.loader\.(?:[JW]ar|Properties)Launcher$/ + end + def main_class JavaBuildpack::Util::JavaMainUtils.main_class(@application, @configuration) end @@ -78,10 +83,6 @@ def manifest_class_path values.nil? ? [] : values.split(' ').map { |value| @droplet.root + value } end - def port - main_class =~ /^org\.springframework\.boot\.loader\.(?:[JW]ar|Properties)Launcher$/ ? 'SERVER_PORT=$PORT' : nil - end - end end diff --git a/lib/java_buildpack/container/spring_boot.rb b/lib/java_buildpack/container/spring_boot.rb index ea8ec2660b..fd240948fd 100644 --- a/lib/java_buildpack/container/spring_boot.rb +++ b/lib/java_buildpack/container/spring_boot.rb @@ -35,7 +35,8 @@ def initialize(context) # (see JavaBuildpack::Container::DistZipLike#release) def release - "SERVER_PORT=$PORT #{super}" + @droplet.environment_variables.add_environment_variable 'SERVER_PORT', '$PORT' + super end protected diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index d3842c2b9f..568ea6847c 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -45,10 +45,12 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release + @droplet.environment_variables.add_environment_variable 'SERVER_PORT', '$PORT' + [ + @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, @droplet.java_opts.as_env_var, - 'SERVER_PORT=$PORT', qualify_path(@droplet.sandbox + 'bin/spring', @droplet.root), 'run', @droplet.additional_libraries.as_classpath, diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 82b2f2d3ee..69033ba064 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -38,6 +38,7 @@ def command @droplet.java_opts.add_system_property 'http.port', '$PORT' [ + @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, @droplet.java_opts.as_env_var, "$PWD/#{(@droplet.sandbox + 'bin/catalina.sh').relative_path_from(@droplet.root)}", diff --git a/lib/java_buildpack/framework/dyna_trace_agent.rb b/lib/java_buildpack/framework/dyna_trace_agent.rb index dfdd2448b7..a6e311a1ff 100644 --- a/lib/java_buildpack/framework/dyna_trace_agent.rb +++ b/lib/java_buildpack/framework/dyna_trace_agent.rb @@ -35,7 +35,6 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts.add_agentpath_with_props(agent_path, name: agent_name, server: server) - # -agentpath:=name=Tomcat_Monitoring,server=ubuntu:9998 end protected diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb new file mode 100644 index 0000000000..435fc0d5dd --- /dev/null +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -0,0 +1,148 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/qualify_path' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Safenet Luna HSM Java Security Provider support. + class LunaSecurityProvider < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download(@version, @uri) { |file| expand file } + @droplet.copy_resources + + credentials = @application.services.find_service(FILTER)['credentials'] + write_host_certificate credentials + write_client_certificate credentials + write_client_private_key credentials + write_host credentials + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.environment_variables.add_environment_variable 'ChrystokiConfigurationPath', @droplet.sandbox + + @droplet.java_opts + .add_system_property('java.security.properties', @droplet.sandbox + 'java.security') + .add_system_property('java.ext.dirs', ext_dirs) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, 'host', 'host-certificate', 'client-private-key', + 'client-certificate' + end + + private + + FILTER = /luna/.freeze + + private_constant :FILTER + + def chrystoki + @droplet.sandbox + 'Chrystoki.conf' + end + + def client_certificate + @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameCert.pem' + end + + def client_private_key + @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameKey.pem' + end + + def expand(file) + with_timing "Expanding Luna Client to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do + Dir.mktmpdir do |root| + root = Pathname.new(root) + + FileUtils.mkdir_p root + shell "tar x#{compression_flag(file)}f #{file.path} -C #{root} --strip 3 2>&1" + + install_client root + end + end + end + + def ext_dirs + "#{qualify_path(@droplet.java_home.root + 'lib/ext', @droplet.root)}:" \ + "#{qualify_path(@droplet.sandbox + 'usr/safenet/lunaclient/jsp/lib', @droplet.root)}" + end + + def host_certificate + @droplet.sandbox + 'usr/safenet/lunaclient/cert/server/CAFile.pem' + end + + def install_client(root) + FileUtils.mkdir_p @droplet.sandbox + + Dir.chdir(@droplet.sandbox) do + shell "#{rpm2cpio} < #{libcrpytoki root} | cpio -id ./usr/safenet/lunaclient/lib/libCryptoki2_64.so" + shell "#{rpm2cpio} < #{lunajsp root} | cpio -id ./usr/safenet/lunaclient/jsp/lib/*" + end + end + + def libcrpytoki(root) + Dir[root + 'libcryptoki-*.x86_64.rpm'][0] + end + + def lunajsp(root) + Dir[root + 'lunajsp-*.x86_64.rpm'][0] + end + + def rpm2cpio + Pathname.new(File.expand_path('../rpm2cpio.py', __FILE__)) + end + + def write_client_certificate(credentials) + FileUtils.mkdir_p client_certificate.parent + client_certificate.open(File::CREAT | File::WRONLY) { |f| f.write credentials['client-certificate'] } + end + + def write_client_private_key(credentials) + FileUtils.mkdir_p client_private_key.parent + client_private_key.open(File::CREAT | File::WRONLY) { |f| f.write credentials['client-private-key'] } + end + + def write_host_certificate(credentials) + FileUtils.mkdir_p host_certificate.parent + host_certificate.open(File::CREAT | File::WRONLY) { |f| f.write credentials['host-certificate'] } + end + + def write_host(credentials) + content = chrystoki.open(File::RDONLY) { |f| f.read } + content.gsub!(/@@HOST@@/, credentials['host']) + + chrystoki.open(File::CREAT | File::WRONLY) do |f| + f.truncate 0 + f.write content + f.sync + end + end + + end + + end +end diff --git a/lib/java_buildpack/framework/rpm2cpio.py b/lib/java_buildpack/framework/rpm2cpio.py new file mode 100755 index 0000000000..83b24fbec0 --- /dev/null +++ b/lib/java_buildpack/framework/rpm2cpio.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Lightweight RPM to CPIO converter. +# Copyright © 2008-2013 Rudá Moura +# + +'''Extract cpio archive from RPM package. + +rpm2cpio converts the RPM on standard input or first parameter to a CPIO archive on standard output. + +Usage: +rpm2cpio < adjtimex-1.20-2.1.i386.rpm | cpio -it +./sbin/adjtimex +./usr/share/doc/adjtimex-1.20 +./usr/share/doc/adjtimex-1.20/COPYING +./usr/share/doc/adjtimex-1.20/COPYRIGHT +./usr/share/doc/adjtimex-1.20/README +./usr/share/man/man8/adjtimex.8.gz +133 blocks +''' + +import sys +import StringIO +import gzip +import subprocess + +try: + import lzma +except ImportError: + HAS_LZMA_MODULE = False +else: + HAS_LZMA_MODULE = True + +RPM_MAGIC = '\xed\xab\xee\xdb' +GZIP_MAGIC = '\x1f\x8b' +XZ_MAGIC = '\xfd7zXZ\x00' + +def gzip_decompress(data): + gzstream = StringIO.StringIO(data) + gzipper = gzip.GzipFile(fileobj=gzstream) + data = gzipper.read() + return data + +def xz_decompress(data): + if HAS_LZMA_MODULE: + return lzma.decompress(data) + unxz = subprocess.Popen(['unxz'], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + data = unxz.communicate(input=data)[0] + return data + +def rpm2cpio(stream_in=sys.stdin, stream_out=sys.stdout): + lead = stream_in.read(96) + if lead[0:4] != RPM_MAGIC: + raise IOError, 'the input is not a RPM package' + data = stream_in.read() + decompress = None + idx = data.find(XZ_MAGIC) + if idx != -1: + decompress = xz_decompress + pos = idx + idx = data.find(GZIP_MAGIC) + if idx != -1 and decompress is None: + decompress = gzip_decompress + pos = idx + if decompress is None: + raise IOError, 'could not find compressed cpio archive' + data = decompress(data[pos:]) + stream_out.write(data) + +if __name__ == '__main__': + if sys.argv[1:]: + try: + fin = open(sys.argv[1]) + rpm2cpio(fin) + fin.close() + except IOError, e: + print 'Error:', sys.argv[1], e + else: + try: + rpm2cpio() + except IOError, e: + print 'Error:', e diff --git a/lib/java_buildpack/repository/configured_item.rb b/lib/java_buildpack/repository/configured_item.rb index f5674d5d33..d4b251b518 100644 --- a/lib/java_buildpack/repository/configured_item.rb +++ b/lib/java_buildpack/repository/configured_item.rb @@ -35,7 +35,7 @@ class << self # @param [Hash] configuration the configuration # @option configuration [String] :repository_root the root directory of the repository # @option configuration [String] :version the version of the file to resolve - # @param [Block, nil] version_validator an optional version validation block + # @yield [Block] optional version_validator to yield to # @return [String] the URI of the chosen version of the file # @return [JavaBuildpack::Util::TokenizedVersion] the chosen version of the file def find_item(component_name, configuration) diff --git a/lib/java_buildpack/util/play/base.rb b/lib/java_buildpack/util/play/base.rb index 3b97c9ebc5..1bfe03c62f 100644 --- a/lib/java_buildpack/util/play/base.rb +++ b/lib/java_buildpack/util/play/base.rb @@ -51,9 +51,10 @@ def jar?(pattern) # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts.add_system_property 'http.port', '$PORT' + @droplet.environment_variables.add_environment_variable 'PATH', "#{@droplet.java_home.root}/bin:$PATH" [ - "PATH=#{@droplet.java_home.root}/bin:$PATH", + @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, qualify_path(start_script, @droplet.root), java_opts diff --git a/resources/luna_security_provider/Chrystoki.conf b/resources/luna_security_provider/Chrystoki.conf new file mode 100644 index 0000000000..24d58978da --- /dev/null +++ b/resources/luna_security_provider/Chrystoki.conf @@ -0,0 +1,32 @@ +Chrystoki2 = { + LibUNIX = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/lib/libCryptoki2.so; + LibUNIX64 = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/lib/libCryptoki2_64.so; +} + +Luna = { + DefaultTimeOut = 500000; + PEDTimeout1 = 100000; + PEDTimeout2 = 100000; + PEDTimeout3 = 10000; + KeypairGenTimeOut = 2700000; + CloningCommandTimeOut = 300000; +} + +CardReader = { + RemoteCommand = 1; +} +LunaSA Client = { + ReceiveTimeout = 20000; + SSLConfigFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/bin/openssl.cnf; + ClientPrivKeyFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/client/ClientNameKey.pem; + ClientCertFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/client/ClientNameCert.pem; + ServerCAFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/server/CAFile.pem; + NetClient = 1; + HtlDir = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/htl/; + ServerName00 = @@HOST@@; + ServerPort00 = 1792; + ServerHtl00 = 0; +} +Misc = { + ToolsDir = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/bin; +} diff --git a/resources/luna_security_provider/java.security b/resources/luna_security_provider/java.security new file mode 100644 index 0000000000..71a05aadbd --- /dev/null +++ b/resources/luna_security_provider/java.security @@ -0,0 +1 @@ +security.provider.10=com.safenetinc.luna.provider.LunaProvider diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index 01933bbd49..2f00cdd087 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -19,6 +19,7 @@ require 'logging_helper' require 'java_buildpack/component/additional_libraries' require 'java_buildpack/component/droplet' +require 'java_buildpack/component/environment_variables' require 'java_buildpack/component/java_opts' require 'java_buildpack/component/immutable_java_home' require 'java_buildpack/util/snake_case' @@ -35,7 +36,8 @@ let(:component_id) { described_class.to_s.split('::').last.snake_case } let(:droplet) do - JavaBuildpack::Component::Droplet.new(additional_libraries, component_id, java_home, java_opts, app_dir) + JavaBuildpack::Component::Droplet.new(additional_libraries, component_id, environment_variables, + java_home, java_opts, app_dir) end let(:sandbox) { droplet.sandbox } @@ -45,6 +47,12 @@ JavaBuildpack::Component::ImmutableJavaHome.new delegate, app_dir end + let(:environment_variables) do + java_opts = JavaBuildpack::Component::EnvironmentVariables.new app_dir + java_opts.concat %w(test-var-2 test-var-1) + java_opts + end + let(:java_opts) do java_opts = JavaBuildpack::Component::JavaOpts.new app_dir java_opts.concat %w(test-opt-2 test-opt-1) diff --git a/spec/fixtures/stub-luna-security-provider.tar b/spec/fixtures/stub-luna-security-provider.tar new file mode 100644 index 0000000000000000000000000000000000000000..9ac56863dff662bf69fa661dde43ded5b6d6e4ef GIT binary patch literal 51200 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 literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/component/droplet_spec.rb b/spec/java_buildpack/component/droplet_spec.rb index 8ed59d49c6..bc876c5d18 100644 --- a/spec/java_buildpack/component/droplet_spec.rb +++ b/spec/java_buildpack/component/droplet_spec.rb @@ -41,6 +41,10 @@ expect(droplet.java_opts).to equal(java_opts) end + it 'returns environment_variables' do + expect(droplet.environment_variables).to equal(environment_variables) + end + it 'returns an existent child if in application' do FileUtils.touch(app_dir + 'test-file') diff --git a/spec/java_buildpack/component/environment_variables_spec.rb b/spec/java_buildpack/component/environment_variables_spec.rb new file mode 100644 index 0000000000..f420400112 --- /dev/null +++ b/spec/java_buildpack/component/environment_variables_spec.rb @@ -0,0 +1,45 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'droplet_helper' +require 'java_buildpack/component/environment_variables' + +describe JavaBuildpack::Component::EnvironmentVariables do + include_context 'droplet_helper' + + let(:variables) { described_class.new droplet.root } + + it 'adds a variable to the collection' do + variables.add_environment_variable 'test-key', 'test-value' + + expect(variables).to include('test-key=test-value') + end + + it 'adds a qualified variable value to the collection' do + variables.add_environment_variable 'test-key', droplet.sandbox + + expect(variables).to include('test-key=$PWD/.java-buildpack/environment_variables') + end + + it 'renders the collection as an environment variable' do + variables.add_environment_variable 'test-key-2', 'test-value-2' + variables.add_environment_variable 'test-key-1', 'test-value-1' + + expect(variables.as_env_vars).to eq('test-key-2=test-value-2 test-key-1=test-value-1') + end + +end diff --git a/spec/java_buildpack/container/dist_zip_like_spec.rb b/spec/java_buildpack/container/dist_zip_like_spec.rb index 4e3d36d583..3c1871fb8b 100644 --- a/spec/java_buildpack/container/dist_zip_like_spec.rb +++ b/spec/java_buildpack/container/dist_zip_like_spec.rb @@ -51,7 +51,8 @@ it 'returns command', app_fixture: 'container_dist_zip' do - expect(component.release).to eq("#{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 test-opt-1\" $PWD/bin/application") + expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} " \ + 'JAVA_OPTS="test-opt-2 test-opt-1" $PWD/bin/application') end end diff --git a/spec/java_buildpack/container/groovy_spec.rb b/spec/java_buildpack/container/groovy_spec.rb index 9e29a5a61b..441d7d75ad 100644 --- a/spec/java_buildpack/container/groovy_spec.rb +++ b/spec/java_buildpack/container/groovy_spec.rb @@ -91,7 +91,7 @@ it 'returns command', app_fixture: 'container_groovy_main_method' do - expect(component.release).to eq("#{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} " \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} " \ '$PWD/.java-buildpack/groovy/bin/groovy -cp $PWD/.additional_libs/test-jar-1.jar:' \ '$PWD/.additional_libs/test-jar-2.jar Application.groovy Alpha.groovy ' \ 'directory/Beta.groovy invalid.groovy') @@ -100,12 +100,16 @@ it 'returns command with included JARs', app_fixture: 'container_groovy_with_jars' do - expect(component.release).to eq("#{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} " \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} " \ '$PWD/.java-buildpack/groovy/bin/groovy -cp $PWD/.additional_libs/test-jar-1.jar:' \ '$PWD/.additional_libs/test-jar-2.jar:$PWD/Alpha.jar:$PWD/directory/Beta.jar ' \ 'Application.groovy invalid.groovy') end + def env_vars_str + "#{environment_variables.join(' ')}" + end + def java_opts_str "\"#{java_opts.join(' ')}\"" end diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index 9f5ccaecfe..6ddf3309bf 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -59,18 +59,19 @@ it 'returns command' do - expect(component.release).to eq("#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD/.:$PWD/." \ - 'additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - " #{java_opts_str} test-java-main-class") + expect(component.release).to eq("test-var-2 test-var-1 #{qualify_path java_home.root, droplet.root}/bin/java " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ + ".additional_libs/test-jar-2.jar #{java_opts_str} test-java-main-class") end end it 'returns additional classpath entries when Class-Path is specified', app_fixture: 'container_main' do - expect(component.release).to eq("#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD/.:$PWD/." \ - 'additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar:$PWD/' \ - "alpha.jar:$PWD/bravo.jar:$PWD/charlie.jar #{java_opts_str} test-main-class") + expect(component.release).to eq("test-var-2 test-var-1 #{qualify_path java_home.root, droplet.root}/bin/java " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ + '.additional_libs/test-jar-2.jar:$PWD/alpha.jar:$PWD/bravo.jar:$PWD/' \ + "charlie.jar #{java_opts_str} test-main-class") end context do @@ -78,34 +79,37 @@ it 'returns command line arguments when they are specified' do - expect(component.release).to eq("#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD/.:$PWD/." \ - 'additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - " #{java_opts_str} test-java-main-class some arguments") + expect(component.release).to eq("test-var-2 test-var-1 #{qualify_path java_home.root, droplet.root}/bin/java " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + "test-jar-2.jar #{java_opts_str} test-java-main-class some arguments") end end it 'releases Spring boot applications with a JarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_jar_launcher' do - expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ - '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - " #{java_opts_str} org.springframework.boot.loader.JarLauncher") + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ + " #{java_opts_str} org.springframework.boot.loader.JarLauncher") end it 'releases Spring boot applications with a WarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_war_launcher' do - expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ - '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - " #{java_opts_str} org.springframework.boot.loader.WarLauncher") + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ + " #{java_opts_str} org.springframework.boot.loader.WarLauncher") end it 'releases Spring boot applications with a PropertiesLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_properties_launcher' do - expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ - '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - " #{java_opts_str} org.springframework.boot.loader.PropertiesLauncher") + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ + " #{java_opts_str} org.springframework.boot.loader.PropertiesLauncher") end context do @@ -113,7 +117,8 @@ it 'releases Spring boot applications with a JarLauncher in the configuration by specifying a port' do - expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp " \ + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java -cp " \ '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ "test-jar-2.jar #{java_opts_str} org.springframework.boot.loader.JarLauncher") end @@ -124,7 +129,8 @@ it 'releases Spring boot applications with a WarLauncher in the configuration by specifying a port' do - expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java -cp " \ + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java -cp " \ '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ "test-jar-2.jar #{java_opts_str} org.springframework.boot.loader.WarLauncher") end @@ -135,7 +141,8 @@ it 'releases Spring boot applications with a PropertiesLauncher in the configuration by specifying a port' do - expect(component.release).to eq("SERVER_PORT=$PORT #{qualify_path java_home.root, droplet.root}/bin/java " \ + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs' \ "/test-jar-2.jar #{java_opts_str} org.springframework.boot.loader." \ 'PropertiesLauncher') diff --git a/spec/java_buildpack/container/ratpack_spec.rb b/spec/java_buildpack/container/ratpack_spec.rb index 71e4414b8d..3a955ad679 100644 --- a/spec/java_buildpack/container/ratpack_spec.rb +++ b/spec/java_buildpack/container/ratpack_spec.rb @@ -69,7 +69,8 @@ it 'returns command', app_fixture: 'container_ratpack_staged' do - expect(component.release).to eq("#{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 test-opt-1\" $PWD/bin/application") + expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 " \ + 'test-opt-1" $PWD/bin/application') end end diff --git a/spec/java_buildpack/container/spring_boot_cli_spec.rb b/spec/java_buildpack/container/spring_boot_cli_spec.rb index a9b93bd3bf..2cdac4a610 100644 --- a/spec/java_buildpack/container/spring_boot_cli_spec.rb +++ b/spec/java_buildpack/container/spring_boot_cli_spec.rb @@ -93,12 +93,16 @@ it 'returns command', app_fixture: 'container_spring_boot_cli_valid_app' do - expect(component.release).to eq("#{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} SERVER_PORT=$PORT " \ - '$PWD/.java-buildpack/spring_boot_cli/bin/spring run ' \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} " \ + "JAVA_OPTS=#{java_opts_str} $PWD/.java-buildpack/spring_boot_cli/bin/spring run " \ '-cp $PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ 'directory/pogo_4.groovy invalid.groovy pogo_1.groovy pogo_2.groovy pogo_3.groovy') end + def env_vars_str + "#{environment_variables.join(' ')}" + end + def java_opts_str "\"#{java_opts.join(' ')}\"" end diff --git a/spec/java_buildpack/container/spring_boot_spec.rb b/spec/java_buildpack/container/spring_boot_spec.rb index c386ee26b8..8968fd640e 100644 --- a/spec/java_buildpack/container/spring_boot_spec.rb +++ b/spec/java_buildpack/container/spring_boot_spec.rb @@ -69,8 +69,16 @@ it 'returns command', app_fixture: 'container_spring_boot_staged' do - expect(component.release).to eq("SERVER_PORT=$PORT #{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 test-opt-1\" " \ - '$PWD/bin/application') + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} " \ + "JAVA_OPTS=#{java_opts_str} $PWD/bin/application") + end + + def env_vars_str + "#{environment_variables.join(' ')}" + end + + def java_opts_str + "\"#{java_opts.join(' ')}\"" end end diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index bb6dd218a0..04c13acb69 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -83,8 +83,8 @@ end it 'returns command' do - expect(component.command).to eq("#{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 test-opt-1 -Dhttp.port=$PORT\" " \ - '$PWD/.java-buildpack/tomcat/bin/catalina.sh run') + expect(component.command).to eq("test-var-2 test-var-1 #{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 " \ + 'test-opt-1 -Dhttp.port=$PORT" $PWD/.java-buildpack/tomcat/bin/catalina.sh run') end end diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb new file mode 100644 index 0000000000..bd1637df70 --- /dev/null +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -0,0 +1,106 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/luna_security_provider' + +describe JavaBuildpack::Framework::LunaSecurityProvider do + include_context 'component_helper' + + it 'does not detect without luna-n/a service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?).with(/luna/, + 'host', + 'host-certificate', + 'client-private-key', + 'client-certificate').and_return(true) + allow(services).to receive(:find_service) + .and_return('credentials' => { 'server' => 'test-server', + 'host' => 'test-host', + 'host-certificate' => 'test-host-cert', + 'client-private-key' => 'test-private-key', + 'client-certificate' => 'test-client-cert' }) + end + + it 'detects with luna-n/a service' do + expect(component.detect).to eq("luna-security-provider=#{version}") + end + + it 'copies resources', + cache_fixture: 'stub-luna-security-provider.tar' do + + component.compile + + expect(sandbox + 'Chrystoki.conf').to exist + expect(sandbox + 'java.security').to exist + end + + it 'unpacks the luna jar', + cache_fixture: 'stub-luna-security-provider.tar' do + + component.compile + + expect(sandbox + 'usr/safenet/lunaclient/lib/libCryptoki2_64.so').to exist + expect(sandbox + 'usr/safenet/lunaclient/jsp/lib/stub.file').to exist + end + + it 'write certificate files', + cache_fixture: 'stub-luna-security-provider.tar' do + + component.compile + + expect(sandbox + 'usr/safenet/lunaclient/cert/server/CAFile.pem').to exist + expect(sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameCert.pem').to exist + expect(sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameKey.pem').to exist + + check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/server/CAFile.pem', 'test-host-cert') + check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameCert.pem', 'test-client-cert') + check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameKey.pem', 'test-private-key') + end + + it 'writes host information', + cache_fixture: 'stub-luna-security-provider.tar' do + + component.compile + + expect(File.read(sandbox + 'Chrystoki.conf')).to include('ServerName00 = test-host') + end + + it 'updates environment variables' do + component.release + expect(environment_variables).to include('ChrystokiConfigurationPath=$PWD/.java-buildpack/luna_security_provider') + end + + it 'updates JAVA_OPTS' do + component.release + expect(java_opts).to include('-Djava.security.properties=$PWD/.java-buildpack/' \ + 'luna_security_provider/java.security') + expect(java_opts).to include('-Djava.ext.dirs=$PWD/.test-java-home/lib/ext:$PWD/.java-buildpack/' \ + 'luna_security_provider/usr/safenet/lunaclient/jsp/lib') + end + + def check_file_contents(file, contents) + expect(File.read(file)).to eq contents + end + + end +end diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index 0e5d51e4a8..d22bd7a14c 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -47,7 +47,7 @@ end it 'returns command' do - expect(play_app.release).to eq("PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ + expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ '$PWD/bin/play-application -Jtest-opt-2 -Jtest-opt-1 -J-Dhttp.port=$PORT') end diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index b086d6025e..6d09736779 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -103,7 +103,7 @@ end it 'returns command' do - expect(play_app.release).to eq("PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ + expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ '$PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') end end @@ -124,7 +124,7 @@ end it 'returns command' do - expect(play_app.release).to eq("PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ + expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ '$PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') end diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index 93cbee12b3..9f17dd6893 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -103,8 +103,8 @@ end it 'returns command' do - expect(play_app.release).to eq("PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} $PWD/start " \ - 'test-opt-2 test-opt-1 -Dhttp.port=$PORT') + expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ + '$PWD/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') end end From 83b743a23f9aeaa3fa3d34fefbd18d90e877e0f9 Mon Sep 17 00:00:00 2001 From: Mike Youngstrom Date: Wed, 12 Aug 2015 16:12:41 +0100 Subject: [PATCH 060/812] Support version 2.0.0 of the memory calculator This commit adds support for version 2.0.0 of the Java Buildpack Memory Calculator. This includes specifying initial memory values which are set to 100% by default in the JRE configuration files in order to preserve existing behaviour. [#99686520][#99679412] --- config/open_jdk_jre.yml | 6 +- config/oracle_jre.yml | 6 +- docs/jre-open_jdk_jre.md | 18 +++++- docs/jre-oracle_jre.md | 18 +++++- .../jre/open_jdk_like_memory_calculator.rb | 41 +++++++++++--- spec/fixtures/stub-memory-calculator.tar.gz | Bin 0 -> 174 bytes .../open_jdk_like_memory_calculator_spec.rb | 52 +++++++++++++++--- spec/java_buildpack/jre/open_jdk_like_spec.rb | 9 ++- 8 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 spec/fixtures/stub-memory-calculator.tar.gz diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 1f39ee6ab6..3c8bb6f050 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -20,7 +20,7 @@ jre: version: 1.8.0_+ repository_root: ! '{default.repository.root}/openjdk/{platform}/{architecture}' memory_calculator: - version: 1.+ + version: 2.+ repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' memory_sizes: heap: @@ -34,3 +34,7 @@ memory_calculator: native: 10 permgen: 10 stack: 5 + memory_initials: + heap: 100% + metaspace: 100% + permgen: 100% diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index 34627cc60e..9b81d3378d 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -23,7 +23,7 @@ jre: version: 1.8.0_+ repository_root: "" memory_calculator: - version: 1.+ + version: 2.+ repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' memory_sizes: heap: @@ -37,3 +37,7 @@ memory_calculator: native: 10 permgen: 10 stack: 5 + memory_initials: + heap: 100% + metaspace: 100% + permgen: 100% \ No newline at end of file diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 8e7f5b8293..21f97edef4 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -21,7 +21,8 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | Name | Description | ---- | ----------- | `memory_sizes` | Optional memory sizes, described below under "Memory Sizes". -| `memory_heuristics` | Default memory size weightings, described below under "Memory Weightings. +| `memory_heuristics` | Default memory size weightings, described below under "Memory Weightings". +| `memory_initials` | Initial memory sizes, described below under "Memory Initials". | `repository_root` | The URL of the OpenJDK repository index ([details][repositories]). | `version` | The version of Java runtime to use. Candidate versions can be found in the listings for [centos6][], [lucid][], [mountainlion][], and [precise][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. @@ -67,6 +68,21 @@ represent a maximum heap size three times as large as the maximum PermGen size, Memory weightings are used together with memory ranges to calculate the amount of memory for each memory type, as follows. +#### Memory Initials +Memory initials are configured in the `memory_initials` mapping of [`config/open_jdk_jre.yml`][]. Each initial is a percentage of the given type of memory. Valid memory types are `heap`, `permgen`, and `metaspace`. For example, the following initials: + +```yaml +memory_initials: + heap: 50% + permgen: 25% +``` + +Given a maximum heap (Xmx) of 1G and a maximum permgen (-XX:MaxPermsize) of 256M an initial heap (Xms) of 512M and an initial permgen (-XX:Permsize) of 64M would be used. + +If no initial value is specified for a memory type the JVM default will be used. + +A value of 100% for each memory types is generally recommended for best performance. Smaller values will potentially preserve unused system memory for other tenants on the same host. Using the G1 garbage collector along with aggressive `MinHeapFreeRatio` and `MaxHeapFreeRatio` values the JVM will actually release unused heap back to the system up to the initial value. + #### Memory Calculation Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index f3877b53f7..350902cf8c 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -30,7 +30,8 @@ The JRE can be configured by modifying the [`config/oracle_jre.yml`][] file in t | Name | Description | ---- | ----------- | `memory_sizes` | Optional memory sizes, described below under "Memory Sizes". -| `memory_heuristics` | Default memory size weightings, described below under "Memory Weightings. +| `memory_heuristics` | Default memory size weightings, described below under "Memory Weightings". +| `memory_initials` | Initial memory sizes, described below under "Memory Initials". | `repository_root` | The URL of the Oracle repository index ([details][repositories]). | `version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. @@ -76,6 +77,21 @@ represent a maximum heap size three times as large as the maximum PermGen size, Memory weightings are used together with memory ranges to calculate the amount of memory for each memory type, as follows. +#### Memory Initials +Memory initials are configured in the `memory_initials` mapping of [`config/oracle_jre.yml`][]. Each initial is a percentage of the given type of memory. Valid memory types are `heap`, `permgen`, and `metaspace`. For example, the following initials: + +```yaml +memory_initials: + heap: 50% + permgen: 25% +``` + +Given a maximum heap (Xmx) of 1G and a maximum permgen (-XX:MaxPermsize) of 256M an initial heap (Xms) of 512M and an initial permgen (-XX:Permsize) of 64M would be used. + +If no initial value is specified for a memory type the JVM default will be used. + +A value of 100% for each memory types is generally recommended for best performance. Smaller values will potentially preserve unused system memory for other tenants on the same host. Using the G1 garbage collector along with aggressive `MinHeapFreeRatio` and `MaxHeapFreeRatio` values the JVM will actually release unused heap back to the system up to the initial value. + #### Memory Calculation Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index fb38af49eb..6e394ea4e8 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -17,6 +17,7 @@ require 'fileutils' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/jre' +require 'java_buildpack/util/shell' require 'java_buildpack/util/qualify_path' require 'open3' @@ -31,21 +32,22 @@ class OpenJDKLikeMemoryCalculator < JavaBuildpack::Component::VersionedDependenc def compile download(@version, @uri) do |file| FileUtils.mkdir_p memory_calculator.parent - FileUtils.cp_r(file.path, memory_calculator) + if @version[0] < '2' + unpack_calculator file + else + unpack_compressed_calculator file + end memory_calculator.chmod 0755 end - shell "#{qualify_path memory_calculator, Pathname.new(Dir.pwd)} -memorySizes=#{memory_sizes @configuration} " \ - "-memoryWeights=#{memory_weights @configuration} -totMemory=$MEMORY_LIMIT" + show_settings memory_calculation_string(Pathname.new(Dir.pwd)) end # Returns a fully qualified memory calculation command to be prepended to the buildpack's command sequence # # @return [String] the memory calculation command def memory_calculation_command - "CALCULATED_MEMORY=$(#{qualify_path memory_calculator, @droplet.root} " \ - "-memorySizes=#{memory_sizes @configuration} -memoryWeights=#{memory_weights @configuration} " \ - '-totMemory=$MEMORY_LIMIT)' + "CALCULATED_MEMORY=$(#{memory_calculation_string(@droplet.root)})" end # (see JavaBuildpack::Component::BaseComponent#release) @@ -66,6 +68,17 @@ def memory_calculator @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{@version}" end + def memory_calculator_tar + platform = `uname -s` =~ /Darwin/ ? 'darwin' : 'linux' + @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{platform}" + end + + def memory_calculation_string(relative_path) + "#{qualify_path memory_calculator, relative_path} -memorySizes=#{memory_sizes @configuration} " \ + "-memoryWeights=#{memory_weights @configuration} -memoryInitials=#{memory_initials @configuration} " \ + '-totMemory=$MEMORY_LIMIT' + end + def memory_sizes(configuration) memory_sizes = version_specific configuration['memory_sizes'] memory_sizes.map { |k, v| "#{k}:#{v}" }.join(',') @@ -76,6 +89,20 @@ def memory_weights(configuration) memory_sizes.map { |k, v| "#{k}:#{v}" }.join(',') end + def memory_initials(configuration) + memory_sizes = version_specific configuration['memory_initials'] + memory_sizes.map { |k, v| "#{k}:#{v}" }.join(',') + end + + def unpack_calculator(file) + FileUtils.cp_r(file.path, memory_calculator) + end + + def unpack_compressed_calculator(file) + shell "tar xzf #{file.path} -C #{memory_calculator.parent} 2>&1" + FileUtils.mv(memory_calculator_tar, memory_calculator) + end + def version_specific(configuration) if @droplet.java_home.java_8_or_later? configuration.delete 'permgen' @@ -86,7 +113,7 @@ def version_specific(configuration) configuration end - def shell(*args) + def show_settings(*args) Open3.popen3(*args) do |_stdin, stdout, stderr, wait_thr| status = wait_thr.value stderr_content = stderr.gets nil diff --git a/spec/fixtures/stub-memory-calculator.tar.gz b/spec/fixtures/stub-memory-calculator.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8719119c5711fe47f4d85c2ff4548e9bb116ead7 GIT binary patch literal 174 zcmb2|=3t1lI33Es{PvIXwv zly{n0g)S0S7SfE|^3^-p{)U0=(cIG)z8=24Gjokj`n$?MkEhlz`gdjj`dc5j '10', 'permgen' => '10', 'stack' => '5', - 'native' => '10' } } + 'native' => '10' }, + 'memory_initials' => { 'heap' => '100%', + 'metaspace' => '100%', + 'permgen' => '100%' } } end it 'copies executable to bin directory', cache_fixture: 'stub-memory-calculator' do java_home.version = version_7 - allow(component).to receive(:shell) + allow(component).to receive(:show_settings) component.compile @@ -55,22 +58,51 @@ cache_fixture: 'stub-memory-calculator' do java_home.version = version_7 - allow(component).to receive(:shell) + allow(component).to receive(:show_settings) component.compile expect(File.stat(sandbox + "bin/java-buildpack-memory-calculator-#{version}").mode).to eq(0100755) end + context do + + let(:version) { '3.0.0' } + + it 'copies executable to bin directory from a compressed archive', + cache_fixture: 'stub-memory-calculator.tar.gz' do + + java_home.version = version_7 + allow(component).to receive(:show_settings) + + component.compile + + expect(sandbox + "bin/java-buildpack-memory-calculator-#{version}").to exist + end + + it 'chmods executable to 0755 from a compressed archive', + cache_fixture: 'stub-memory-calculator.tar.gz' do + + java_home.version = version_7 + allow(component).to receive(:show_settings) + + component.compile + + expect(File.stat(sandbox + "bin/java-buildpack-memory-calculator-#{version}").mode).to eq(0100755) + end + + end + it 'runs the memory calculator to sanity check', cache_fixture: 'stub-memory-calculator' do java_home.version = version_7 memory_calculator = qualify_path(sandbox + "bin/java-buildpack-memory-calculator-#{version}", Pathname.new(Dir.pwd)) - expect(component).to receive(:shell).with("#{memory_calculator} -memorySizes=permgen:64m.. " \ - '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ - '-totMemory=$MEMORY_LIMIT') + expect(component).to receive(:show_settings).with("#{memory_calculator} -memorySizes=permgen:64m.. " \ + '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ + '-memoryInitials=heap:100%,permgen:100% ' \ + '-totMemory=$MEMORY_LIMIT') component.compile end @@ -81,7 +113,9 @@ expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -memorySizes=permgen:64m.. ' \ - '-memoryWeights=heap:75,permgen:10,stack:5,native:10 -totMemory=$MEMORY_LIMIT)') + '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ + '-memoryInitials=heap:100%,permgen:100% ' \ + '-totMemory=$MEMORY_LIMIT)') end it 'create memory calculation command for Java 8' do @@ -90,7 +124,9 @@ expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -memorySizes=metaspace:64m.. ' \ - '-memoryWeights=heap:75,metaspace:10,stack:5,native:10 -totMemory=$MEMORY_LIMIT)') + '-memoryWeights=heap:75,metaspace:10,stack:5,native:10 ' \ + '-memoryInitials=heap:100%,metaspace:100% ' \ + '-totMemory=$MEMORY_LIMIT)') end it 'adds $CALCULATED_MEMORY to the JAVA_OPTS' do diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index a48ee787d5..8f560b5039 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -45,7 +45,10 @@ 'metaspace' => '10', 'permgen' => '10', 'stack' => '5', - 'native' => '10' } } + 'native' => '10' }, + 'memory_initials' => { 'heap' => '100%', + 'metaspace' => '100%', + 'permgen' => '100%' } } end it 'always supports' do @@ -67,7 +70,9 @@ java_home.version = version_7 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -memorySizes=permgen:64m.. ' \ - '-memoryWeights=heap:75,permgen:10,stack:5,native:10 -totMemory=$MEMORY_LIMIT)') + '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ + '-memoryInitials=heap:100%,permgen:100% ' \ + '-totMemory=$MEMORY_LIMIT)') end end From 485c4552f9465b7e4dcf0acb0bdab43087e4637b Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 13 Aug 2015 13:13:39 +0100 Subject: [PATCH 061/812] Configure number of stack threads for memory This commit adds the ability to configure the number of threads the memory calculator should use when calculating the stack to allocate per thread. The default behaviour of the Java Buildpack is unchanged. [#91088912] --- config/open_jdk_jre.yml | 1 + config/oracle_jre.yml | 1 + docs/jre-open_jdk_jre.md | 12 ++++++++++-- docs/jre-oracle_jre.md | 12 ++++++++++-- .../jre/open_jdk_like_memory_calculator.rb | 16 ++++++++++------ .../jre/open_jdk_like_memory_calculator_spec.rb | 17 +++++++++++++++++ 6 files changed, 49 insertions(+), 10 deletions(-) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 3c8bb6f050..dafcb25b01 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -22,6 +22,7 @@ jre: memory_calculator: version: 2.+ repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' + stack_threads: memory_sizes: heap: metaspace: 64m.. diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index 9b81d3378d..b706b23eb2 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -25,6 +25,7 @@ jre: memory_calculator: version: 2.+ repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' + stack_threads: memory_sizes: heap: metaspace: 64m.. diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 21f97edef4..ef12e0e366 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -30,9 +30,9 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/open_jdk_jre` directory in the buildpack fork. For example, to add the JCE Unlimited Strength `local_policy.jar` add your file to `resources/open_jdk_jre/lib/security/local_policy.jar`. ### Memory -The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes` and/or `memory_heuristics` mappings. +The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials` and/or `stack_threads` mappings. -Note: if the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the appication is started. +Note: if the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. #### Memory Sizes The following optional properties may be specified in the `memory_sizes` mapping. @@ -83,6 +83,14 @@ If no initial value is specified for a memory type the JVM default will be used. A value of 100% for each memory types is generally recommended for best performance. Smaller values will potentially preserve unused system memory for other tenants on the same host. Using the G1 garbage collector along with aggressive `MinHeapFreeRatio` and `MaxHeapFreeRatio` values the JVM will actually release unused heap back to the system up to the initial value. +#### Stack Threads + +The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory then it should be specified like the following example: + +```yaml +stack_threads: 500 +``` + #### Memory Calculation Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 350902cf8c..77889138f9 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -39,9 +39,9 @@ The JRE can be configured by modifying the [`config/oracle_jre.yml`][] file in t The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/oracle_jre` directory in the buildpack fork. For example, to add the JCE Unlimited Strength `local_policy.jar` add your file to `resources/oracle_jre/lib/security/local_policy.jar`. ### Memory -The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes` and/or `memory_heuristics` mappings. +The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials` and/or `stack_threads` mappings. -Note: if the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the appication is started. +Note: if the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. #### Memory Sizes The following optional properties may be specified in the `memory_sizes` mapping. @@ -92,6 +92,14 @@ If no initial value is specified for a memory type the JVM default will be used. A value of 100% for each memory types is generally recommended for best performance. Smaller values will potentially preserve unused system memory for other tenants on the same host. Using the G1 garbage collector along with aggressive `MinHeapFreeRatio` and `MaxHeapFreeRatio` values the JVM will actually release unused heap back to the system up to the initial value. +#### Stack Threads + +The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory then it should be specified like the following example: + +```yaml +stack_threads: 500 +``` + #### Memory Calculation Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 6e394ea4e8..fb84674aaf 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -75,8 +75,8 @@ def memory_calculator_tar def memory_calculation_string(relative_path) "#{qualify_path memory_calculator, relative_path} -memorySizes=#{memory_sizes @configuration} " \ - "-memoryWeights=#{memory_weights @configuration} -memoryInitials=#{memory_initials @configuration} " \ - '-totMemory=$MEMORY_LIMIT' + "-memoryWeights=#{memory_weights @configuration} -memoryInitials=#{memory_initials @configuration}" \ + "#{stack_threads @configuration} -totMemory=$MEMORY_LIMIT" end def memory_sizes(configuration) @@ -85,13 +85,13 @@ def memory_sizes(configuration) end def memory_weights(configuration) - memory_sizes = version_specific configuration['memory_heuristics'] - memory_sizes.map { |k, v| "#{k}:#{v}" }.join(',') + memory_heuristics = version_specific configuration['memory_heuristics'] + memory_heuristics.map { |k, v| "#{k}:#{v}" }.join(',') end def memory_initials(configuration) - memory_sizes = version_specific configuration['memory_initials'] - memory_sizes.map { |k, v| "#{k}:#{v}" }.join(',') + memory_initials = version_specific configuration['memory_initials'] + memory_initials.map { |k, v| "#{k}:#{v}" }.join(',') end def unpack_calculator(file) @@ -103,6 +103,10 @@ def unpack_compressed_calculator(file) FileUtils.mv(memory_calculator_tar, memory_calculator) end + def stack_threads(configuration) + configuration['stack_threads'] ? " -stackThreads=#{configuration['stack_threads']}" : '' + end + def version_specific(configuration) if @droplet.java_home.java_8_or_later? configuration.delete 'permgen' diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index cf99b366ef..3edfc6c678 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -135,4 +135,21 @@ expect(java_opts).to include('$CALCULATED_MEMORY') end + context do + + let(:configuration) { super().merge 'stack_threads' => '200' } + + it 'create memory calculation command with stack threads specified' do + java_home.version = version_7 + command = component.memory_calculation_command + + expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ + 'java-buildpack-memory-calculator-0.0.0 -memorySizes=permgen:64m.. ' \ + '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ + '-memoryInitials=heap:100%,permgen:100% ' \ + '-stackThreads=200 -totMemory=$MEMORY_LIMIT)') + end + + end + end From 54e95ba54c81a5c69fc8b927002225da78bb01dc Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 13 Aug 2015 13:14:29 +0100 Subject: [PATCH 062/812] Memory calculator docs improvement Add tags information to the memory calculator documentation. [#101134594] --- docs/jre-open_jdk_jre.md | 2 +- docs/jre-oracle_jre.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index ef12e0e366..2865816639 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -8,7 +8,7 @@ The OpenJDK JRE provides Java runtimes from the [OpenJDK][] project. Versions o Tags - open-jdk=⟨version⟩ + open-jdk=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩ Tags are printed to standard output by the buildpack detect script diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 77889138f9..321bd81feb 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -8,7 +8,7 @@ The Oracle JRE provides Java runtimes from [Oracle][] project. No versions of t Tags - oracle=⟨version⟩ + oracle=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩ Tags are printed to standard output by the buildpack detect script From 0cf8e421a2b1b39501a528a24a88c10574ffd550 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 13 Aug 2015 16:39:49 +0100 Subject: [PATCH 063/812] Update New Relic resources Update the New Relic configuration file to the latest version. [#101135042] --- resources/new_relic_agent/newrelic.yml | 163 ++++++++++++++----------- 1 file changed, 93 insertions(+), 70 deletions(-) diff --git a/resources/new_relic_agent/newrelic.yml b/resources/new_relic_agent/newrelic.yml index 5e9507b4b9..2123748db4 100644 --- a/resources/new_relic_agent/newrelic.yml +++ b/resources/new_relic_agent/newrelic.yml @@ -1,24 +1,36 @@ -# # This file configures the New Relic Agent. New Relic monitors -# Java applications with deep visibility and low overhead. For more -# information, visit www.newrelic.com. -# +# Java applications with deep visibility and low overhead. For more details and additional +# configuration options visit https://docs.newrelic.com/docs/java/java-agent-configuration. # # This section is for settings common to all environments. # Do not add anything above this next line. common: &default_settings - # - # ============================== LICENSE KEY =============================== + # ============================== LICENSE KEY =============================== # You must specify the license key associated with your New Relic # account. This key binds your Agent's data to your account in the # New Relic service. - license_key: '' + license_key: 'your license key' # Agent Enabled - # Use this setting to force the agent to run or not run. + # Use this setting to disable the agent instead of removing it from the startup command. # Default is true. - # agent_enabled: true + agent_enabled: true + + # Set the name of your application as you'd like it show up in New Relic. + # If enable_auto_app_naming is false, the agent reports all data to this application. + # Otherwise, the agent reports only background tasks (transactions for non-web applications) + # to this application. To report data to more than one application + # (useful for rollup reporting), separate the application names with ";". + # For example, to report data to "My Application" and "My Application 2" use this: + # app_name: My Application;My Application 2 + # This setting is required. + app_name: My Application + + # To enable high security, set this property to true. When in high + # security mode, the agent will use SSL and obfuscated SQL. Additionally, + # request parameters and message parameters will not be sent to New Relic. + high_security: false # Set to true to enable support for auto app naming. # The name of each web app is detected automatically @@ -33,43 +45,35 @@ common: &default_settings # Default is true. enable_auto_transaction_naming: true - # Set the name of your application as you'd like it show up in New Relic. - # if enable_auto_app_naming is false, the agent reports all data to this application. - # Otherwise, the agent reports only background tasks (transactions for non-web applications) to this application. - # To report data to more than one application, separate the application names with ";". - # For example, to report data to"My Application" and "My Application 2" use this: - # app_name: My Application;My Application 2 - # This setting is required. - app_name: My Application - # The agent uses its own log file to keep its logging # separate from that of your application. Specify the log level here. # This setting is dynamic, so changes do not require restarting your application. - # The levels in increasing order of verboseness are: off, severe, warning, info, fine, finer, finest + # The levels in increasing order of verboseness are: + # off, severe, warning, info, fine, finer, finest # Default is info. log_level: info - # Log all data to and from New Relic in plain text. + # Log all data sent to and from New Relic in plain text. # This setting is dynamic, so changes do not require restarting your application. # Default is false. - #audit_mode: true + audit_mode: false - # The number of log files to use. + # The number of backup log files to save. # Default is 1. - #log_file_count: 1 + log_file_count: 1 # The maximum number of bytes to write to any one log file. # The log_file_count must be set greater than 1. # Default is 0 (no limit). - #log_limit_in_kbytes: 0 + log_limit_in_kbytes: 0 # Override other log rolling configuration and roll the logs daily. # Default is false. - #log_daily: false + log_daily: false # The name of the log file. # Default is newrelic_agent.log. - #log_file_name: newrelic_agent.log + log_file_name: newrelic_agent.log # The log file directory. # Default is the logs directory in the newrelic.jar parent directory. @@ -84,27 +88,36 @@ common: &default_settings # Default is true. ssl: true - # Proxy settings for connecting to the New Relic server. - # + # Proxy settings for connecting to the New Relic server: # If a proxy is used, the host setting is required. Other settings # are optional. Default port is 8080. The username and password # settings will be used to authenticate to Basic Auth challenges # from a proxy server. - # - # proxy_host: hostname - # proxy_port: 8080 - # proxy_user: username - # proxy_password: password - - # Tells transaction tracer and error collector (when enabled) - # whether or not to capture HTTP params. When true, frameworks can - # exclude HTTP parameters from being captured. - # Default is false. - capture_params: false + #proxy_host: hostname + #proxy_port: 8080 + #proxy_user: username + #proxy_password: password + + # Limits the number of lines to capture for each stack trace. + # Default is 30 + max_stack_trace_lines: 30 + + # Provides the ability to configure the attributes sent to New Relic. These + # attributes can be found in transaction traces, traced errors, Insight's + # transaction events, and Insight's page views. + attributes: + + # When true, attributes will be sent to New Relic. The default is true. + enabled: true + + #A comma separated list of attribute keys whose values should + # be sent to New Relic. + #include: + + # A comma separated list of attribute keys whose values should + # not be sent to New Relic. + #exclude: - # Tells transaction tracer and error collector to not to collect - # specific http request parameters. - # ignored_params: credit_card, ssn, password # Transaction tracer captures deep information about slow # transactions and sends this to the New Relic service once a @@ -112,8 +125,8 @@ common: &default_settings # the transactions including any SQL statements issued. transaction_tracer: - # Transaction tracer is enabled by default. Set this to false to - # turn it off. This feature is only available at the higher product levels. + # Transaction tracer is enabled by default. Set this to false to turn it off. + # This feature is not available to Lite accounts and is automatically disabled. # Default is true. enabled: true @@ -133,10 +146,6 @@ common: &default_settings # Default is obfuscated. record_sql: obfuscated - # Obfuscate only occurrences of specific SQL fields names. - # This setting only applies if "record_sql" is set to "raw". - #obfuscated_sql_fields: credit_card, ssn, password - # Set this to true to log SQL statements instead of recording them. # SQL is logged using the record_sql mode. # Default is false. @@ -165,64 +174,78 @@ common: &default_settings # Default is 20. top_n: 20 - # Error collector captures information about uncaught exceptions and - # sends them to New Relic for viewing + # sends them to New Relic for viewing. error_collector: - # Error collector is enabled by default. Set this to false to turn - # it off. This feature is only available at the higher product levels. + # This property enables the collection of errors. If the property is not + # set or the property is set to false, then errors will not be collected. # Default is true. enabled: true - # To stop specific exceptions from reporting to New Relic, set this property - # to a comma separated list of full class names. - # - # ignore_errors: + # Use this property to exclude specific exceptions from being reported as errors + # by providing a comma separated list of full class names. + # The default is to exclude akka.actor.ActorKilledException. If you want to override + # this, you must provide any new value as an empty list is ignored. + ignore_errors: akka.actor.ActorKilledException - # To stop specific http status codes from being reporting to New Relic as errors, - # set this property to a comma separated list of status codes to ignore. - # When this property is commented out it defaults to ignoring 404s. - # - # ignore_status_codes: 404 + # Use this property to exclude specific http status codes from being reported as errors + # by providing a comma separated list of status codes. + # The default is to exclude 404s. If you want to override + # this, you must provide any new value as an empty list is ignored. + ignore_status_codes: 404 + + # Analytics Events are used for Histograms and Percentiles. Unaggregated data is collected + # for each web transaction and sent to the server on harvest. + analytics_events: + + # Set to false to disable analytics events. + # Default is true. + enabled: true + + # Events are collected up to the configured amount. Afterwards, events are sampled to + # maintain an even distribution across the harvest cycle. Largest value accepted is 10000. + # Default is 2000. Setting to 0 will disable. + max_samples_stored: 2000 # Cross Application Tracing adds request and response headers to - # external calls using the Apache HttpClient libraries to provided better + # external calls using supported HTTP libraries to provide better # performance data when calling applications monitored by other New Relic Agents. - # cross_application_tracer: - # Set to true to enable cross application tracing. + + # Set to false to disable cross application tracing. # Default is true. enabled: true # Thread profiler measures wall clock time, CPU time, and method call counts # in your application's threads as they run. + # This feature is not available to Lite accounts and is automatically disabled. thread_profiler: # Set to false to disable the thread profiler. # Default is true. enabled: true - #============================== Browser Monitoring =============================== # New Relic Real User Monitoring gives you insight into the performance real users are # experiencing with your website. This is accomplished by measuring the time it takes for # your users' browsers to download and render your web pages by injecting a small amount # of JavaScript code into the header and footer of each page. browser_monitoring: + # By default the agent automatically inserts API calls in compiled JSPs to - # inject the monitoring JavaScript into web pages. + # inject the monitoring JavaScript into web pages. Not all rendering engines are supported. + # See https://docs.newrelic.com/docs/java/real-user-monitoring-in-java#manual_instrumentation + # for instructions to add these manually to your pages. # Set this attribute to false to turn off this behavior. auto_instrument: true - # Set this attribute to false to prevent injection of the monitoring JavaScript. - # Default is true. - enabled: true + # Application Environments # ------------------------------------------ # Environment specific settings are in this section. # You can use the environment to override the default settings. # For example, to change the app_name setting. -# Use -Dnewrelic.environment= on the Java command line +# Use -Dnewrelic.environment= on the Java startup command line # to set the environment. # The default environment is production. From 229250ad530dcdada5c9845f71aaece40f0fa2eb Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 13 Aug 2015 16:59:52 +0100 Subject: [PATCH 064/812] Be more tolerant of existing env vars during tests The download cache tests can fail if certain environment variables exist on the users machine. This commit makes those tests more tolerant of this. [#101130824] --- spec/java_buildpack/util/cache/download_cache_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 0de45f2100..fb1b477db8 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -172,7 +172,7 @@ context do - let(:environment) { { 'http_proxy' => 'http://proxy:9000' } } + let(:environment) { { 'http_proxy' => 'http://proxy:9000', 'HTTP_PROXY' => nil } } it 'uses http_proxy if specified' do stub_request(:get, uri) @@ -189,7 +189,7 @@ context do - let(:environment) { { 'HTTP_PROXY' => 'http://proxy:9000' } } + let(:environment) { { 'HTTP_PROXY' => 'http://proxy:9000', 'http_proxy' => nil } } it 'uses HTTP_PROXY if specified' do stub_request(:get, uri) @@ -206,7 +206,7 @@ context do - let(:environment) { { 'https_proxy' => 'http://proxy:9000' } } + let(:environment) { { 'https_proxy' => 'http://proxy:9000', 'HTTPS_PROXY' => nil } } it 'uses https_proxy if specified and URL is secure' do stub_request(:get, uri_secure) @@ -223,7 +223,7 @@ context do - let(:environment) { { 'HTTPS_PROXY' => 'http://proxy:9000' } } + let(:environment) { { 'HTTPS_PROXY' => 'http://proxy:9000', 'https_proxy' => nil } } it 'uses HTTPS_PROXY if specified and URL is secure' do stub_request(:get, uri_secure) From 01862708d9d3df35d5e3228a7cc72a0b2289eca9 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 14 Aug 2015 08:48:48 -0700 Subject: [PATCH 065/812] Tomcat Context Path This change updates the Tomcat container to allow a user to configure the context path that an application is exposed at. Previously, the application was always exposed at the root ('/') but this didn't work for many applications that had hard-coded context-path assumptions. In addition, changes to the Cloud Foundry router mean that applications can now be routed via both a host and a context path. [#101289516] --- README.md | 26 ++++++++++-------- config/tomcat.yml | 1 + docs/container-tomcat.md | 17 +++++++++++- .../container/tomcat/tomcat_instance.rb | 3 ++- .../container/tomcat/tomcat_instance_spec.rb | 27 +++++++++++++++++++ 5 files changed, 61 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 0122e7e46c..4fdce4c02c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The `java-buildpack` is a [Cloud Foundry][] buildpack for running JVM-based appl To use this buildpack specify the URI of the repository when pushing an application to Cloud Foundry: ```bash -cf push -p -b https://github.com/cloudfoundry/java-buildpack.git +$ cf push -p -b https://github.com/cloudfoundry/java-buildpack.git ``` ## Examples @@ -29,11 +29,15 @@ The buildpack supports extension through the use of Git repository forking. The Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml. For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. -```cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '[jre: {version: 1.7.0_+}, memory_calculator: {memory_heuristics: {heap: 85, stack: 10}}]'``` +```bash +$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE 'jre: { version: 1.7.0_+ }' +``` If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. -```cf set-env my-application JBP_CONFIG_REPOSITORY '[ default_repository_root: "http://repo.example.io" ]'``` +```bash +$ cf set-env my-application JBP_CONFIG_REPOSITORY 'default_repository_root: "http://repo.example.io"' +``` Environment variable can also be specified in the applications `manifest` file. See the [Environment Variables][] documentation for more information. @@ -92,8 +96,8 @@ The buildpack can be packaged up so that it can be uploaded to Cloud Foundry usi The online package is a version of the buildpack that is as minimal as possible and is configured to connect to the network for all dependencies. This package is about 50K in size. To create the online package, run: ```bash -bundle install -bundle exec rake package +$ bundle install +$ bundle exec rake package ... Creating build/java-buildpack-cfd6b17.zip ``` @@ -104,8 +108,8 @@ The offline package is a version of the buildpack designed to run without access To pin the version of dependencies used by the buildpack to the ones currently resolvable use the `PINNED=true` argument. This will update the [`config/` directory][] to contain exact version of each dependency instead of version ranges. ```bash -bundle install -bundle exec rake package OFFLINE=true PINNED=true +$ bundle install +$ bundle exec rake package OFFLINE=true PINNED=true ... Creating build/java-buildpack-offline-cfd6b17.zip ``` @@ -114,8 +118,8 @@ Creating build/java-buildpack-offline-cfd6b17.zip Keeping track of different versions of the buildpack can be difficult. To help with this, the rake `package` task puts a version discriminator in the name of the created package file. The default value for this discriminator is the current Git hash (e.g. `cfd6b17`). To change the version when creating a package, use the `VERSION=` argument: ```bash -bundle install -bundle exec rake package VERSION=2.1 +$ bundle install +$ bundle exec rake package VERSION=2.1 ... Creating build/java-buildpack-2.1.zip ``` @@ -124,8 +128,8 @@ Creating build/java-buildpack-2.1.zip To run the tests, do the following: ```bash -bundle install -bundle exec rake +$ bundle install +$ bundle exec rake ``` [Running Cloud Foundry locally][] is useful for privately testing new features. diff --git a/config/tomcat.yml b/config/tomcat.yml index 381842e751..fcaebd3a57 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -18,6 +18,7 @@ tomcat: version: 8.0.+ repository_root: ! '{default.repository.root}/tomcat' + context_path: lifecycle_support: version: 2.+ repository_root: ! '{default.repository.root}/tomcat-lifecycle-support' diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index 1b08a8932f..5170477d9a 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -12,7 +12,7 @@ The Tomcat Container allows servlet 2 and 3 web applications to be run. These a Tags are printed to standard output by the buildpack detect script -If the application uses Spring, [Spring profiles][] can be specified by setting the [`SPRING_PROFILES_ACTIVE`][] environment variable. This is automatically detected and used by Spring. The Spring Auto-reconfiguration Framework will specify the `cloud` profile in addition to any others. +If the application uses Spring, [Spring profiles][] can be specified by setting the [`SPRING_PROFILES_ACTIVE`][] environment variable. This is automatically detected and used by Spring. The Spring Auto-reconfiguration Framework will specify the `cloud` profile in addition to any others. ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. @@ -45,9 +45,24 @@ The container can be configured by modifying the [`config/tomcat.yml`][] file in | `redis_store.repository_root` | The URL of the Redis Store repository index ([details][repositories]). | `redis_store.timeout` | The Redis connection timeout (in milliseconds). | `redis_store.version` | The version of Redis Store to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/redis-store/index.yml). +| `tomcat.context_path` | The context path to expose the application at. | `tomcat.repository_root` | The URL of the Tomcat repository index ([details][repositories]). | `tomcat.version` | The version of Tomcat to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/tomcat/index.yml). +### Common configurations +The version of Tomcat can be configured by setting an environment variable. + +``` +$ cf set-env my-application JBP_CONFIG_TOMCAT 'tomcat: { version: 7.0.+ }' +``` + +The context path that an application is deployed at can be configured by setting an environment variable. + +``` +$ cf set-env my-application JBP_CONFIG_TOMCAT 'tomcat: { context_path: /first-segement/second-segment }' +``` + + ### Additional Resources The container can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/tomcat` directory in the buildpack fork. For example, to override the default `logging.properties` add your custom file to `resources/tomcat/conf/logging.properties`. diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index 181ffbbe2a..581af1bc88 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -98,7 +98,8 @@ def expand(file) end def root - tomcat_webapps + 'ROOT' + context_path = (@configuration['context_path'] || 'ROOT').sub(%r{^/}, '').gsub(%r{/}, '#') + tomcat_webapps + context_path end def tomcat_datasource_jar diff --git a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb index 35df1e7dab..2b0272ff38 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb @@ -95,6 +95,33 @@ expect(root_webapp + '.test-file').not_to exist end + context do + let(:configuration) { { 'context_path' => '/first-segment/second-segment' } } + + it 'links only the application files and directories to the ROOT webapp', + app_fixture: 'container_tomcat_with_index', + cache_fixture: 'stub-tomcat.tar.gz' do + + FileUtils.touch(app_dir + '.test-file') + + component.compile + + root_webapp = app_dir + '.java-buildpack/tomcat/webapps/first-segment#second-segment' + + web_inf = root_webapp + 'WEB-INF' + expect(web_inf).to exist + expect(web_inf).to be_symlink + expect(web_inf.readlink).to eq((app_dir + 'WEB-INF').relative_path_from(root_webapp)) + + index = root_webapp + 'index.html' + expect(index).to exist + expect(index).to be_symlink + expect(index.readlink).to eq((app_dir + 'index.html').relative_path_from(root_webapp)) + + expect(root_webapp + '.test-file').not_to exist + end + end + it 'links the Tomcat datasource JAR to the ROOT webapp when that JAR is present', app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat7.tar.gz' do From 2126174ba4f959d7d0451f5dfbff3e24f5d6b675 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Mon, 17 Aug 2015 16:38:05 +0100 Subject: [PATCH 066/812] Update no container message Update the no container found message to provide a more descriptive explanation and point users to further information. [#101396370] --- lib/java_buildpack/buildpack.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index d02c8fd4dd..c7099b77d1 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -58,7 +58,7 @@ def compile puts BUILDPACK_MESSAGE % @buildpack_version container = component_detection('container', @containers, true).first - fail 'No container can run this application' unless container + no_container unless container component_detection('JRE', @jres, true).first.compile component_detection('framework', @frameworks, false).each(&:compile) @@ -71,7 +71,7 @@ def compile # @return [String] The payload required to run the application. def release container = component_detection('container', @containers, true).first - fail 'No container can run this application' unless container + no_container unless container commands = [] commands << component_detection('JRE', @jres, true).first.release @@ -176,6 +176,12 @@ def names(components) components.map { |component| component.class.to_s.space_case }.join(', ') end + def no_container + fail 'No container can run this application. Please ensure that you’ve pushed a valid JVM artifact or ' \ + 'artifacts using the -p command line argument or path manifest entry. Information about valid JVM ' \ + 'artifacts can be found at https://github.com/cloudfoundry/java-buildpack#additional-documentation. ' + end + def require_component(component) file = LOAD_ROOT + "#{component.snake_case}.rb" From a326d16e8acf095795d0221c20280288cd3f0605 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 18 Aug 2015 11:01:07 +0100 Subject: [PATCH 067/812] Update AppDynamics dependency range --- config/app_dynamics_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 81e3f0d3a2..76d77180b7 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -15,7 +15,7 @@ # Configuration for the New Relic framework --- -version: 4.0.+ +version: 4.1.+ repository_root: ! '{default.repository.root}/app-dynamics' default_node_name: ! '$(expr "$VCAP_APPLICATION" : ''.*instance_index[": ]*\([[:digit:]]*\).*'')' default_tier_name: CloudFoundry From d4c4c2fbb02b9662e4bbce1cc4f8eb26d11b976d Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 18 Aug 2015 11:04:36 +0100 Subject: [PATCH 068/812] Update MariaDB dependency range --- config/maria_db_jdbc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/maria_db_jdbc.yml b/config/maria_db_jdbc.yml index ced631ed81..db68ffd72b 100644 --- a/config/maria_db_jdbc.yml +++ b/config/maria_db_jdbc.yml @@ -15,5 +15,5 @@ # Configuration for the MariaDB JDBC framework --- -version: 1.1.+ +version: 1.2.+ repository_root: ! '{default.repository.root}/mariadb-jdbc' From 2e59e52fdeeec430a72ef3945975b456c58a77e8 Mon Sep 17 00:00:00 2001 From: James Bayer Date: Wed, 19 Aug 2015 13:56:15 -0700 Subject: [PATCH 069/812] Documentation for Custom SSL Certificates Previously the documentation for the JREs mentioned how to use the resources directory to copy artifacts, but did not have any explicit examples of where doing this might be useful. This change updates that documentation to provide examples of configuring JCE Unlimited Strength and custom SSL certificates. [#216] --- docs/jre-open_jdk_jre.md | 12 +++++++++--- docs/jre-oracle_jre.md | 11 ++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 2865816639..4d77dfaad3 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -27,7 +27,13 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | `version` | The version of Java runtime to use. Candidate versions can be found in the listings for [centos6][], [lucid][], [mountainlion][], and [precise][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. ### Additional Resources -The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/open_jdk_jre` directory in the buildpack fork. For example, to add the JCE Unlimited Strength `local_policy.jar` add your file to `resources/open_jdk_jre/lib/security/local_policy.jar`. +The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/open_jdk_jre` directory in the buildpack fork. + +#### JCE Unlimited Strength +To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resources/open_jdk_jre/lib/security/local_policy.jar`. This file will be overlayed onto the OpenJDK distribution. + +#### Custom CA Certificates +To add custom SSL certificates, add your `cacerts` file to `resources/open_jdk_jre/lib/security/cacerts`. This file will be overlayed onto the OpenJDK distribution. ### Memory The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials` and/or `stack_threads` mappings. @@ -85,14 +91,14 @@ A value of 100% for each memory types is generally recommended for best performa #### Stack Threads -The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory then it should be specified like the following example: +The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory then it should be specified like the following example: ```yaml stack_threads: 500 ``` #### Memory Calculation -Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. +Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. The total available memory is allocated into heap, Metaspace or PermGen (depending on the version of Oracle), stack, and native memory types. diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 321bd81feb..bae9c1cb7a 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -36,8 +36,13 @@ The JRE can be configured by modifying the [`config/oracle_jre.yml`][] file in t | `version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. ### Additional Resources -The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/oracle_jre` directory in the buildpack fork. For example, to add the JCE Unlimited Strength `local_policy.jar` add your file to `resources/oracle_jre/lib/security/local_policy.jar`. +The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/oracle_jre` directory in the buildpack fork. +#### JCE Unlimited Strength +To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resources/oracle_jre/lib/security/local_policy.jar`. This file will be overlayed onto the Oracle distribution. + +#### Custom CA Certificates +To add custom SSL certificates, add your `cacerts` file to `resources/oracle_jre/lib/security/cacerts`. This file will be overlayed onto the Oracle distribution. ### Memory The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials` and/or `stack_threads` mappings. @@ -94,14 +99,14 @@ A value of 100% for each memory types is generally recommended for best performa #### Stack Threads -The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory then it should be specified like the following example: +The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory then it should be specified like the following example: ```yaml stack_threads: 500 ``` #### Memory Calculation -Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. +Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. The total available memory is allocated into heap, Metaspace or PermGen (depending on the version of Oracle), stack, and native memory types. From 53f901b091ab9410bdd7528718148dcbc11a535c Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 20 Aug 2015 15:40:12 +0100 Subject: [PATCH 070/812] Support configuration of Java Main applications Adds a config file for Java Main applications to allow it to be configured by environment variables without forking the buildpack. [#101680106] --- config/java_main.yml | 19 +++++++++++++++++++ docs/container-java_main.md | 5 +++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 config/java_main.yml diff --git a/config/java_main.yml b/config/java_main.yml new file mode 100644 index 0000000000..622015343e --- /dev/null +++ b/config/java_main.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Java Main container +--- +java_main_class: +arguments: diff --git a/docs/container-java_main.md b/docs/container-java_main.md index d311e85a2d..7bb7450dbb 100644 --- a/docs/container-java_main.md +++ b/docs/container-java_main.md @@ -23,15 +23,16 @@ If the application uses Spring, [Spring profiles][] can be specified by setting ## Spring Boot If the main class is Spring Boot's `JarLauncher`, `PropertiesLauncher` or `WarLauncher`, the Java Main Container adds a `--server.port` argument to the command so that the application uses the correct port. + ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. -The container can be configured by creating or modifying the `config/java_main.yml` file in the buildpack fork. +The container can be configured by modifying the `config/java_main.yml` file in the buildpack fork. | Name | Description | ---- | ----------- | `arguments` | Optional command line arguments to be passed to the Java main class. The arguments are specified as a single YAML scalar in plain style or enclosed in single or double quotes. -| `java_main_class` | The Java class name to run. Values containing whitespace are rejected with an error, but all others values appear without modification on the Java command line. If not specified, the Java Manifest value of `Main-Class` is used. +| `java_main_class` | Optional Java class name to run. Values containing whitespace are rejected with an error, but all others values appear without modification on the Java command line. If not specified, the Java Manifest value of `Main-Class` is used. [Configuration and Extension]: ../README.md#configuration-and-extension [Spring profiles]:http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/ From 103fc4ad819e80391d585587b184f6ceda1bc4af Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 27 Aug 2015 16:35:58 +0100 Subject: [PATCH 071/812] Change capitalization of AppDynamics name where possible This commit updates the appearense of the AppDynamics name where possible to more closely match their branding but without causing a breaking change to the buildpacks backwards compatibility. [#102165010] --- README.md | 2 +- ...ork-app_dynamics_agent.md => framework-appdynamics_agent.md} | 0 lib/java_buildpack/framework/app_dynamics_agent.rb | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename docs/{framework-app_dynamics_agent.md => framework-appdynamics_agent.md} (100%) diff --git a/README.md b/README.md index 4fdce4c02c..2651cf3018 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Spring Boot CLI](docs/container-spring_boot_cli.md) ([Configuration](docs/container-spring_boot_cli.md#configuration)) * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) * Standard Frameworks - * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) + * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-appdynamics_agent.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [DynaTrace Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-appdynamics_agent.md similarity index 100% rename from docs/framework-app_dynamics_agent.md rename to docs/framework-appdynamics_agent.md diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index dfcaaf81c1..f76893f3f6 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -26,7 +26,7 @@ class AppDynamicsAgent < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_zip false + download_zip(false, @droplet.sandbox, 'AppDynamics Agent') @droplet.copy_resources end From f062497a96f146b3cca74c5ccd07fa4ac93fd23c Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 1 Sep 2015 11:56:02 +0100 Subject: [PATCH 072/812] Change capitalization of AppDynamics name where possible Aditional work to update the appearense of the AppDynamics name where possible to more closely match their branding but without causing a breaking change to the buildpacks backwards compatibility. The buidpack will match services with both `app-dynamics` and `appdynamics` as service names/tags etc... [#102165010] --- README.md | 2 +- ...ork-appdynamics_agent.md => framework-app_dynamics_agent.md} | 0 lib/java_buildpack/framework/app_dynamics_agent.rb | 2 +- spec/java_buildpack/framework/app_dynamics_agent_spec.rb | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename docs/{framework-appdynamics_agent.md => framework-app_dynamics_agent.md} (100%) diff --git a/README.md b/README.md index 2651cf3018..4fdce4c02c 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Spring Boot CLI](docs/container-spring_boot_cli.md) ([Configuration](docs/container-spring_boot_cli.md#configuration)) * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) * Standard Frameworks - * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-appdynamics_agent.md#configuration)) + * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [DynaTrace Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) diff --git a/docs/framework-appdynamics_agent.md b/docs/framework-app_dynamics_agent.md similarity index 100% rename from docs/framework-appdynamics_agent.md rename to docs/framework-app_dynamics_agent.md diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index f76893f3f6..9d0919761d 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -55,7 +55,7 @@ def supports? private - FILTER = /app-dynamics/.freeze + FILTER = /app[-]?dynamics/.freeze private_constant :FILTER diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 632fbd2d34..99d8d28fb4 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -35,7 +35,7 @@ let(:credentials) { {} } before do - allow(services).to receive(:one_service?).with(/app-dynamics/, 'host-name').and_return(true) + allow(services).to receive(:one_service?).with(/app[-]?dynamics/, 'host-name').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => credentials) end From 2bd1a97dc3e9d89ba934139ec17f990f70814dd6 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 1 Sep 2015 15:01:45 +0100 Subject: [PATCH 073/812] Change capitalization of AppDynamics name where possible Documentation change [#102165010] --- docs/framework-app_dynamics_agent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 098d807777..3d18ff6e7f 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -13,7 +13,7 @@ The AppDynamics Agent Framework causes an application to be automatically config Tags are printed to standard output by the buildpack detect script ## User-Provided Service -When binding AppDynamics using a user-provided service, it must have name or tag with `app-dynamics` in it. The credential payload can contain the following entries: +When binding AppDynamics using a user-provided service, it must have name or tag with `app-dynamics` or `appdynamics` in it. The credential payload can contain the following entries: | Name | Description | ---- | ----------- From 6677165dd19cd75287130aaa2c36fffd5ea26c75 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 2 Sep 2015 14:51:56 +0100 Subject: [PATCH 074/812] Change capitalization of AppDynamics name where possible Documentation change [#102165010] --- docs/framework-app_dynamics_agent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 3d18ff6e7f..3fa1eae4dc 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -3,7 +3,7 @@ The AppDynamics Agent Framework causes an application to be automatically config - From 9ce1872d0e220432b454416e45ef19f28785d628 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 3 Sep 2015 12:16:14 -0700 Subject: [PATCH 075/812] Remove CentOS and Lucid Support This change removes CentOS and Lucid support from the buildpack. [#101134432] --- docs/extending-repositories.md | 4 ++-- docs/jre-open_jdk_jre.md | 5 ++--- rakelib/package.rb | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/extending-repositories.md b/docs/extending-repositories.md index 82e5ea9434..6942b0c111 100644 --- a/docs/extending-repositories.md +++ b/docs/extending-repositories.md @@ -55,7 +55,7 @@ end | Variable | Description | | -------- | ----------- | | `{default.repository.root}` | The common root for all repositories. Currently defaults to `http://download.pivotal.io.s3.amazonaws.com`. -| `{platform}` | The platform that the application is running on. Currently detects `centos6`, `lucid`, `mountainlion`, and `precise`. +| `{platform}` | The platform that the application is running on. Currently detects `mountainlion`, `precise`, and `trusty`. | `{architecture}` | The architecture of the system as returned by Ruby. The value is typically one of `x86_64` or `x86`. ## Configuration @@ -95,5 +95,5 @@ In addition to declaring a specific versions to use, you can also specify a boun [`config/repository.yml`]: ../config/repository.yml [`JavaBuildpack::Repository::ConfiguredItem`]: ../lib/java_buildpack/repository/configured_item.rb [Configuration and Extension]: ../README.md#configuration-and-extension -[example]: http://download.pivotal.io.s3.amazonaws.com/openjdk/lucid/x86_64/index.yml +[example]: http://download.pivotal.io.s3.amazonaws.com/openjdk/trusty/x86_64/index.yml diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 4d77dfaad3..e335503326 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -24,7 +24,7 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | `memory_heuristics` | Default memory size weightings, described below under "Memory Weightings". | `memory_initials` | Initial memory sizes, described below under "Memory Initials". | `repository_root` | The URL of the OpenJDK repository index ([details][repositories]). -| `version` | The version of Java runtime to use. Candidate versions can be found in the listings for [centos6][], [lucid][], [mountainlion][], and [precise][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `version` | The version of Java runtime to use. Candidate versions can be found in the listings for [mountainlion][], [precise][], and [trusty][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. ### Additional Resources The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/open_jdk_jre` directory in the buildpack fork. @@ -108,11 +108,10 @@ Termination is guaranteed since there is a finite number of memory types and in [`config/open_jdk_jre.yml`]: ../config/open_jdk_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension -[centos6]: http://download.pivotal.io.s3.amazonaws.com/openjdk/centos6/x86_64/index.yml [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[lucid]: http://download.pivotal.io.s3.amazonaws.com/openjdk/lucid/x86_64/index.yml [mountainlion]: http://download.pivotal.io.s3.amazonaws.com/openjdk/mountainlion/x86_64/index.yml [OpenJDK]: http://openjdk.java.net [precise]: http://download.pivotal.io.s3.amazonaws.com/openjdk/precise/x86_64/index.yml [repositories]: extending-repositories.md +[trusty]: http://download.pivotal.io.s3.amazonaws.com/openjdk/trusty/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/rakelib/package.rb b/rakelib/package.rb index 4e5bf15744..18148c471f 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -32,7 +32,7 @@ def self.version BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze - PLATFORMS = %w(centos6 lucid mountainlion precise trusty).freeze + PLATFORMS = %w(mountainlion precise trusty).freeze STAGING_DIR = "#{BUILD_DIR}/staging".freeze From 69abec6d2726f73a22339caa6ae7739f060002e4 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Fri, 4 Sep 2015 11:57:31 +0100 Subject: [PATCH 076/812] Change to AppDynamics `tier_name` resolution This commit sets the `default_application_name` and `default_tier_name` to empty properties in the AppDynamics config file. This mean they can be easily set by an environment variable. If they are left empty and no value is given by the credentials payload of the bound AppDynamics service, then `application_name` already uses to the application name set by Cloud Foundry but the `tier_name` will now also use the application name set by Cloud Foundry for its value. [#102469346] --- config/app_dynamics_agent.yml | 3 ++- docs/framework-app_dynamics_agent.md | 12 ++++++------ lib/java_buildpack/framework/app_dynamics_agent.rb | 3 ++- .../framework/app_dynamics_agent_spec.rb | 7 ++++--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 76d77180b7..44f2f5fd4f 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -17,5 +17,6 @@ --- version: 4.1.+ repository_root: ! '{default.repository.root}/app-dynamics' +default_application_name: default_node_name: ! '$(expr "$VCAP_APPLICATION" : ''.*instance_index[": ]*\([[:digit:]]*\).*'')' -default_tier_name: CloudFoundry +default_tier_name: diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 3fa1eae4dc..e1f8af624a 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -13,7 +13,7 @@ The AppDynamics Agent Framework causes an application to be automatically config Tags are printed to standard output by the buildpack detect script ## User-Provided Service -When binding AppDynamics using a user-provided service, it must have name or tag with `app-dynamics` or `appdynamics` in it. The credential payload can contain the following entries: +When binding AppDynamics using a user-provided service, it must have name or tag with `app-dynamics` or `appdynamics` in it. The credential payload can contain the following entries: | Name | Description | ---- | ----------- @@ -31,18 +31,18 @@ To provide more complex values such as the `tier-name`, using the interactive mo ## Configuration For general information on configuring the buildpack, refer to [Configuration and Extension][]. -The framework can be configured by modifying the [`config/app_dynamics_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. +The framework can be configured by modifying the [`config/app_dynamics_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. | Name | Description | ---- | ----------- -| `default_application_name` | This is not provided by default but can be added to specify the application name in the AppDynamics dashboard. This can be overridden with an `application-name` entry in the credentials payload. -| `default_tier_name` | The default tier name for this application in the AppDynamics dashboard. This can be overridden with a `tier-name` entry in the credentials payload. -| `default_node_name` | The default node name for this application in the AppDynamics dashboard. The default value is an expression that will be evaluated based on the `instance_index` of the application. This can be overridden with a `node-name` entry in the credentials payload. +| `default_application_name` | This is omitted by default but can be added to specify the application name in the AppDynamics dashboard. This can be overridden by an `application-name` entry in the credentials payload. If neither are supplied the default is the `application_name` as specified by Cloud Foundry. +| `default_node_name` | The default node name for this application in the AppDynamics dashboard. The default value is an expression that will be evaluated based on the `instance_index` of the application. This can be overridden by a `node-name` entry in the credentials payload. +| `default_tier_name` | This is omitted by default but can be added to specify the tier name for this application in the AppDynamics dashboard. This can be overridden by a `tier-name` entry in the credentials payload. If neither are supplied the default is the `application_name` as specified by Cloud Foundry. | `repository_root` | The URL of the AppDynamics repository index ([details][repositories]). | `version` | The version of AppDynamics to use. Candidate versions can be found in [this listing][]. ### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/app_dynamics_agent` directory in the buildpack fork. For example, to override the default `app-agent-config.xml` add your custom file to `resources/app_dynamics_agent/conf/app-agent-config.xml`. +The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/app_dynamics_agent` directory in the buildpack fork. For example, to override the default `app-agent-config.xml` add your custom file to `resources/app_dynamics_agent/conf/app-agent-config.xml`. [`config/app_dynamics_agent.yml`]: ../config/app_dynamics_agent.yml [AppDynamics Service]: http://www.appdynamics.com diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 9d0919761d..1eb08d7252 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -97,7 +97,8 @@ def ssl_enabled(java_opts, credentials) end def tier_name(java_opts, credentials) - name = credentials['tier-name'] || @configuration['default_tier_name'] + name = credentials['tier-name'] || @configuration['default_tier_name'] || + @application.details['application_name'] java_opts.add_system_property('appdynamics.agent.tierName', "#{name}") end diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 99d8d28fb4..db949bd9db 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -22,8 +22,9 @@ include_context 'component_helper' let(:configuration) do - { 'default_tier_name' => 'test-tier-name', - 'default_node_name' => "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')" } + { 'default_tier_name' => nil, + 'default_node_name' => "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')", + 'default_application_name' => nil } end it 'does not detect without app-dynamics-n/a service' do @@ -65,7 +66,7 @@ expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/app_dynamics_agent/javaagent.jar') expect(java_opts).to include('-Dappdynamics.controller.hostName=test-host-name') expect(java_opts).to include('-Dappdynamics.agent.applicationName=test-application-name') - expect(java_opts).to include('-Dappdynamics.agent.tierName=test-tier-name') + expect(java_opts).to include('-Dappdynamics.agent.tierName=test-application-name') expect(java_opts).to include('-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : ' \ '\'.*instance_index[": ]*\\([[:digit:]]*\\).*\')') end From 5c66fe720fe74890713982c5cba9d18f7f9dfcb7 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Fri, 4 Sep 2015 15:00:55 +0100 Subject: [PATCH 077/812] New Relic to give priority to java_opts This commit changes the ordering of the frameworks so that Java Opts from either the environment or the Java Opts config file will be specified after any Java Opts added by other frameworks in the application start command. [#102143072] --- config/components.yml | 7 +++++-- docs/framework-java_opts.md | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/config/components.yml b/config/components.yml index 4b30dc02b2..b63de955d3 100644 --- a/config/components.yml +++ b/config/components.yml @@ -31,13 +31,15 @@ jres: - "JavaBuildpack::Jre::OpenJdkJRE" # - "JavaBuildpack::Jre::OracleJRE" +# Frameworks are processed in order. Any Java Opts added by the JavaOpts framework will be specified in the start +# command after any Java Opts added by previous frameworks. + frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" # - "JavaBuildpack::Framework::IntroscopeAgent" # - "JavaBuildpack::Framework::DynaTraceAgent" - - "JavaBuildpack::Framework::JavaOpts" - "JavaBuildpack::Framework::JrebelAgent" -# - "JavaBuildpack::Framework::LunaSecurityProvider" +# - "JavaBuildpack::Framework::LunaSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration" @@ -45,3 +47,4 @@ frameworks: - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" + - "JavaBuildpack::Framework::JavaOpts" diff --git a/docs/framework-java_opts.md b/docs/framework-java_opts.md index 02e8237761..24527e42e7 100644 --- a/docs/framework-java_opts.md +++ b/docs/framework-java_opts.md @@ -27,6 +27,8 @@ The framework can be configured by creating or modifying the [`config/java_opts. Any `JAVA_OPTS` from either the config file or environment variables that configure memory options will cause deployment to fail as they're not allowed. Memory options are configured by the buildpack and may not be modified. +Any `JAVA_OPTS` from either the config file or environment variables will be specified in the start command after any Java Opts added by other frameworks. + ## Example ```yaml # JAVA_OPTS configuration From 3b680248235a081525d4be1662fa637dce19d737 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 9 Sep 2015 15:22:37 +0100 Subject: [PATCH 078/812] Changes required for Spring Insight on PCF 1.5.x This commit makes a number of changes which are required for compatibility with Spring Insight on PCF 1.5.x. Close #222 [#102664842] --- .../framework/spring_insight.rb | 100 +++++++++--------- spec/fixtures/stub-insight-agent.jar | Bin 1724 -> 7109 bytes .../framework/spring_insight_spec.rb | 65 ++++++++---- 3 files changed, 94 insertions(+), 71 deletions(-) diff --git a/lib/java_buildpack/framework/spring_insight.rb b/lib/java_buildpack/framework/spring_insight.rb index 1d841c380a..2db96ddd5f 100644 --- a/lib/java_buildpack/framework/spring_insight.rb +++ b/lib/java_buildpack/framework/spring_insight.rb @@ -33,7 +33,7 @@ class SpringInsight < JavaBuildpack::Component::BaseComponent # @param [Hash] context a collection of utilities used the component def initialize(context) super(context) - @version, @uri, @agent_id, @agent_pass = supports? ? find_insight_agent : [nil, nil, nil, nil] + @version, @uri, @agent_transport = find_insight_agent if supports? end # (see JavaBuildpack::Component::BaseComponent#detect) @@ -45,8 +45,7 @@ def detect def compile JavaBuildpack::Util::Cache::InternetAvailability.instance.available( true, 'The Spring Insight download location is always accessible') do - # TODO: AGENT_DOWNLOAD_URI_SUFFIX To be removed once the full path is included in VCAP_SERVICES see #58873498 - download(@version, @uri.chomp('/') + AGENT_DOWNLOAD_URI_SUFFIX) { |file| expand file } + download(@version, @uri) { |file| expand file } end end @@ -58,15 +57,11 @@ def release .add_system_property('insight.logs', logs_directory) .add_system_property('aspectj.overweaving', true) .add_system_property('org.aspectj.tracing.factory', 'default') - .add_system_property('insight.transport.type', 'HTTP') - - add_agent_configuration end protected - # The unique identifier of the component, incorporating the version of the dependency (e.g. - # +spring-insight=1.9.3+) + # The unique identifier of the component, incorporating the version of the dependency) # # @param [String] version the version of the dependency # @return [String] the unique identifier of the component @@ -76,24 +71,9 @@ def id(version) private - # TODO: To be removed once the full path is included in VCAP_SERVICES see issue 58873498 - AGENT_DOWNLOAD_URI_SUFFIX = '/services/config/agent-download'.freeze - - FILTER = /insight/.freeze + FILTER = /p-insight/.freeze - private_constant :AGENT_DOWNLOAD_URI_SUFFIX, :FILTER - - def add_agent_configuration - @droplet.java_opts - .add_system_property('agent.http.protocol', 'http') - .add_system_property('agent.http.host', URI(@uri).host) - .add_system_property('agent.http.port', 80) - .add_system_property('agent.http.context.path', 'insight') - .add_system_property('agent.http.username', @agent_id) - .add_system_property('agent.http.password', @agent_pass) - .add_system_property('agent.http.send.json', false) - .add_system_property('agent.http.use.proxy', false) - end + private_constant :FILTER def expand(file) with_timing "Expanding Spring Insight to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do @@ -112,6 +92,9 @@ def unpack_agent_installer(root, file) FileUtils.mkdir_p(agent_dir) shell "unzip -qq #{file.path} -d #{installer_dir} 2>&1" shell "unzip -qq #{uber_agent_zip(installer_dir)} -d #{agent_dir} 2>&1" + move agent_dir, + installer_dir + 'answers.properties', + installer_dir + 'agent.override.properties' agent_dir end @@ -119,35 +102,34 @@ def unpack_agent_installer(root, file) def install_insight(agent_dir) root = Pathname.glob(agent_dir + 'springsource-insight-uber-agent-*')[0] - init_container_libs root - init_insight_cloudfoundry_agent_plugin root init_insight root + init_insight_properties agent_dir init_insight_agent_plugins root init_weaver root end - def init_container_libs(root) - move container_libs_directory, - root + 'agents/common/insight-bootstrap-generic-*.jar', - root + 'agents/tomcat/7/lib/insight-bootstrap-tomcat-common-*.jar', - root + 'agents/tomcat/7/lib/insight-agent-*.jar' - end - def init_insight(root) move insight_directory, root + 'insight/collection-plugins', - root + 'insight/conf' + root + 'insight/conf', + root + 'insight/bootstrap', + root + 'insight/extras' end - def init_insight_agent_plugins(root) - move insight_directory + 'agent-plugins', - root + 'transport/http/insight-agent-http-*.jar', - root + 'cloudfoundry/insight-agent-cloudfoundry-*.jar' + def init_insight_properties(root) + move insight_directory, + root + 'agent.override.properties' + + answers_properties = root + 'answers.properties' + insight_properties = insight_directory + 'conf/insight.properties' + system "cat #{answers_properties} >> #{insight_properties}" end - def init_insight_cloudfoundry_agent_plugin(root) - move container_libs_directory, - root + 'cloudfoundry/cloudfoundry-runtime-*.jar' + def init_insight_agent_plugins(root) + move insight_directory + 'agent-plugins', + root + 'agents/tomcat/7/lib/insight-agent-*.jar' + transport_jar = transport_plugin root + move insight_directory + 'agent-plugins', transport_jar end def init_weaver(root) @@ -155,18 +137,13 @@ def init_weaver(root) root + 'cloudfoundry/insight-weaver-*.jar' end - def container_libs_directory - @droplet.root + '.spring-insight/container-libs' - end - def find_insight_agent service = @application.services.find_service FILTER - version = service['label'].match(/(.*)-(.*)/)[2] credentials = service['credentials'] - uri = credentials['dashboard_url'] - id = credentials['agent_username'] - pass = credentials['agent_password'] - [version, uri, id, pass] + version = credentials['version'] || '1.0.0' + uri = credentials['agent_download_url'] + transport = credentials['agent_transport'] || 'rabbitmq' + [version, uri, transport] end def insight_directory @@ -186,7 +163,7 @@ def move(destination, *globs) end def supports? - @application.services.one_service? FILTER, 'dashboard_url', 'agent_username', 'agent_password' + @application.services.one_service? FILTER, 'agent_download_url', 'service_instance_id' end def uber_agent_zip(location) @@ -203,6 +180,25 @@ def weaver_jar (weaver_directory + 'insight-weaver-*.jar').glob[0] end + def transport_plugin(root) + return root + 'transport/http/insight-agent-http-*.jar' if http_transport? + return root + 'transport/rabbitmq/insight-agent-rabbitmq-*.jar' if rabbit_transport? + (root + 'transport/activemq/insight-agent-activemq-*.jar') if active_transport? + end + + def http_transport? + @agent_transport.eql? 'http' + end + + def rabbit_transport? + @agent_transport.eql? 'rabbitmq' + end + + def active_transport? + @agent_transport.eql? 'activemq' + end + end + end end diff --git a/spec/fixtures/stub-insight-agent.jar b/spec/fixtures/stub-insight-agent.jar index 6148c8743f898785d0a97cbd7ddcea25947301a2..c5ecfa11d067287c072702830c3e9e55dda4641a 100644 GIT binary patch literal 7109 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 diff --git a/spec/java_buildpack/framework/spring_insight_spec.rb b/spec/java_buildpack/framework/spring_insight_spec.rb index 721a4fa541..ab0139b3d3 100644 --- a/spec/java_buildpack/framework/spring_insight_spec.rb +++ b/spec/java_buildpack/framework/spring_insight_spec.rb @@ -31,39 +31,41 @@ context do before do - allow(services).to receive(:one_service?).with(/insight/, 'dashboard_url', 'agent_username', 'agent_password') - .and_return(true) - allow(services).to receive(:find_service).and_return('label' => 'insight-1.0', - 'credentials' => { 'dashboard_url' => 'test-uri', - 'agent_password' => 'foo', - 'agent_username' => 'bar' }) - allow(application_cache).to receive(:get).with('test-uri/services/config/agent-download') + allow(services).to receive(:one_service?) + .with(/p-insight/, 'agent_download_url', 'service_instance_id').and_return(true) + allow(services).to receive(:find_service) + .and_return('label' => 'p-insight', + 'credentials' => { + 'version' => '2.0.0', + 'agent_download_url' => 'test-uri/services/config/agent-download', + 'agent_password' => 'foo', + 'agent_username' => 'bar', + 'service_instance_id' => '12345' }) + allow(application_cache).to receive(:get) + .with('test-uri/services/config/agent-download') .and_yield(Pathname.new('spec/fixtures/stub-insight-agent.jar').open, false) end - it 'detects with spring-insight-n/a service' do - expect(component.detect).to eq('spring-insight=1.0') + it 'does detect with spring-insight-n/a service' do + expect(component.detect).to eq('spring-insight=2.0.0') end - it 'extracts Spring Insight from the Uber Agent zip file inside the Agent Installer jar' do + it 'does extract Spring Insight from the Uber Agent zip file inside the Agent Installer jar' do component.compile - container_libs_dir = app_dir + '.spring-insight/container-libs' - - expect(sandbox + 'weaver/insight-weaver-cf-2.0.0-CI-SNAPSHOT.jar').to exist - expect(container_libs_dir + 'insight-bootstrap-generic-2.0.0-CI-SNAPSHOT.jar').to exist - expect(container_libs_dir + 'insight-bootstrap-tomcat-common-2.0.0-CI-SNAPSHOT.jar').to exist + expect(sandbox + 'weaver/insight-weaver-2.0.0-CI-SNAPSHOT.jar').to exist expect(sandbox + 'insight/conf/insight.properties').to exist + expect(sandbox + 'insight/agent-plugins/insight-agent-rabbitmq-core-2.0.0-CI-SNAPSHOT.jar').to exist end - it 'guarantees that internet access is available when downloading' do + it 'does guarantee that internet access is available when downloading' do expect_any_instance_of(JavaBuildpack::Util::Cache::InternetAvailability) .to receive(:available).with(true, 'The Spring Insight download location is always accessible') component.compile end - it 'updates JAVA_OPTS', + it 'does update JAVA_OPTS', app_fixture: 'framework_spring_insight' do component.release @@ -74,9 +76,34 @@ expect(java_opts).to include('-Dinsight.logs=$PWD/.java-buildpack/spring_insight/insight/logs') expect(java_opts).to include('-Daspectj.overweaving=true') expect(java_opts).to include('-Dorg.aspectj.tracing.factory=default') - expect(java_opts).to include('-Dagent.http.username=bar') - expect(java_opts).to include('-Dagent.http.password=foo') end end + context do + + it 'does extract Spring Insight from the Uber Agent zip file and copy the ActiveMQ plugin' do + allow(services).to receive(:one_service?) + .with(/p-insight/, 'agent_download_url', 'service_instance_id').and_return(true) + allow(services).to receive(:find_service) + .and_return('label' => 'p-insight', + 'credentials' => { + 'version' => '2.0.0', + 'agent_download_url' => 'test-uri/services/config/agent-download', + 'agent_password' => 'foo', + 'agent_username' => 'bar', + 'service_instance_id' => '12345', + 'agent_transport' => 'activemq' }) + allow(application_cache).to receive(:get) + .with('test-uri/services/config/agent-download') + .and_yield(Pathname.new('spec/fixtures/stub-insight-agent.jar').open, false) + + component.compile + + expect(sandbox + 'weaver/insight-weaver-2.0.0-CI-SNAPSHOT.jar').to exist + expect(sandbox + 'insight/conf/insight.properties').to exist + expect(sandbox + 'insight/agent-plugins/insight-agent-activemq-2.0.0-CI-SNAPSHOT.jar').to exist + end + + end + end From 6843c2f87aa50aa2ee62be689081f828ca5bcc2d Mon Sep 17 00:00:00 2001 From: Nikhil Katre Date: Thu, 10 Sep 2015 14:47:10 -0700 Subject: [PATCH 079/812] Update app_dynamics_agent.yml Changed name from new relic to appdynamics --- config/app_dynamics_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 44f2f5fd4f..ff4395b1bf 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Configuration for the New Relic framework +# Configuration for the AppDynamics framework --- version: 4.1.+ repository_root: ! '{default.repository.root}/app-dynamics' From 5a43f31135271c1e4bb229a3ff0d63383cbe4439 Mon Sep 17 00:00:00 2001 From: imod Date: Tue, 15 Sep 2015 09:32:31 +0200 Subject: [PATCH 080/812] document local_policy.jar location for 'server jre' --- docs/jre-oracle_jre.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index bae9c1cb7a..bc2e5121bd 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -39,7 +39,7 @@ The JRE can be configured by modifying the [`config/oracle_jre.yml`][] file in t The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/oracle_jre` directory in the buildpack fork. #### JCE Unlimited Strength -To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resources/oracle_jre/lib/security/local_policy.jar`. This file will be overlayed onto the Oracle distribution. +To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resources/oracle_jre/lib/security/local_policy.jar`. In case you you'r using the 'server jre', then the file should go to `resources/oracle_jre/jre/lib/security/local_policy.jar`. This file will be overlayed onto the Oracle distribution. #### Custom CA Certificates To add custom SSL certificates, add your `cacerts` file to `resources/oracle_jre/lib/security/cacerts`. This file will be overlayed onto the Oracle distribution. From 649b9f9c20359689ca8cba0a5f24c0d15851c479 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 15 Sep 2015 15:36:42 +0100 Subject: [PATCH 081/812] Improve documentation on setting config variables This commit improves the documentation around using environment variables to set configuration values. This includes some new examples of how to set values from an applications manifest file. [#102675140] --- README.md | 22 +++++++++++++++---- docs/container-groovy.md | 2 +- docs/container-java_main.md | 2 +- docs/container-spring_boot_cli.md | 2 +- docs/container-tomcat.md | 2 +- docs/extending-caches.md | 2 +- docs/extending-logging.md | 2 +- docs/extending-repositories.md | 2 +- docs/framework-app_dynamics_agent.md | 2 +- docs/framework-dyna_trace_agent.md | 2 +- docs/framework-introscope_agent.md | 2 +- docs/framework-java_opts.md | 2 +- docs/framework-jrebel_agent.md | 2 +- docs/framework-luna_security_provider.md | 2 +- docs/framework-maria_db_jdbc.md | 2 +- docs/framework-new_relic_agent.md | 2 +- ...ork-play_framework_auto_reconfiguration.md | 2 +- docs/framework-play_framework_jpa_plugin.md | 2 +- docs/framework-postgresql_jdbc.md | 2 +- docs/framework-spring_auto_reconfiguration.md | 2 +- docs/jre-open_jdk_jre.md | 2 +- docs/jre-oracle_jre.md | 2 +- 22 files changed, 39 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 4fdce4c02c..438cf75651 100644 --- a/README.md +++ b/README.md @@ -27,19 +27,33 @@ The following are _very_ simple examples for deploying the artifact types that w ## Configuration and Extension The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. -Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml. For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. +Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec. For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. ```bash -$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE 'jre: { version: 1.7.0_+ }' +$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '[jre: { version: 1.7.0_+ }]' ``` If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. ```bash -$ cf set-env my-application JBP_CONFIG_REPOSITORY 'default_repository_root: "http://repo.example.io"' +$ cf set-env my-application JBP_CONFIG_REPOSITORY '[default_repository_root: "http://repo.example.io"]' ``` -Environment variable can also be specified in the applications `manifest` file. See the [Environment Variables][] documentation for more information. +Environment variable can also be specified in the applications `manifest` file. For example, to specify an environment variable in an applications manifest file that disables Auto-reconfiguration. + +```bash + env: + JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '[enabled: false]' +``` + +This final example shows how to change the version of Tomcat that is used by the buildpack with an environment variable specified in the applications manifest file. + +```bash + env: + JBP_CONFIG_TOMCAT: '[tomcat: { version: 8.0.+ }]' +``` + +See the [Environment Variables][] documentation for more information. To learn how to configure various properties of the buildpack, follow the "Configuration" links below. More information on extending the buildpack is available [here](docs/extending.md). diff --git a/docs/container-groovy.md b/docs/container-groovy.md index ae78650ab4..06e763684d 100644 --- a/docs/container-groovy.md +++ b/docs/container-groovy.md @@ -22,7 +22,7 @@ Tags are printed to standard output by the buildpack detect script Any JAR files found in the application are automatically added to the classpath at runtime. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The container can be configured by modifying the [`config/groovy.yml`][] file in the buildpack fork. The container uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/container-java_main.md b/docs/container-java_main.md index 7bb7450dbb..a6bef89e6b 100644 --- a/docs/container-java_main.md +++ b/docs/container-java_main.md @@ -25,7 +25,7 @@ If the application uses Spring, [Spring profiles][] can be specified by setting If the main class is Spring Boot's `JarLauncher`, `PropertiesLauncher` or `WarLauncher`, the Java Main Container adds a `--server.port` argument to the command so that the application uses the correct port. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The container can be configured by modifying the `config/java_main.yml` file in the buildpack fork. diff --git a/docs/container-spring_boot_cli.md b/docs/container-spring_boot_cli.md index 4c0d82ac8f..93199f21ca 100644 --- a/docs/container-spring_boot_cli.md +++ b/docs/container-spring_boot_cli.md @@ -22,7 +22,7 @@ Tags are printed to standard output by the buildpack detect script. If the application uses Spring, [Spring profiles][] can be specified by setting the [`SPRING_PROFILES_ACTIVE`][] environment variable. This is automatically detected and used by Spring. The Spring Auto-reconfiguration Framework will specify the `cloud` profile in addition to any others. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The container can be configured by modifying the [`config/spring_boot_cli.yml`][] file in the buildpack fork. The container uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index 5170477d9a..1d133fd76a 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -15,7 +15,7 @@ Tags are printed to standard output by the buildpack detect script If the application uses Spring, [Spring profiles][] can be specified by setting the [`SPRING_PROFILES_ACTIVE`][] environment variable. This is automatically detected and used by Spring. The Spring Auto-reconfiguration Framework will specify the `cloud` profile in addition to any others. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The container can be configured by modifying the [`config/tomcat.yml`][] file in the buildpack fork. The container uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/extending-caches.md b/docs/extending-caches.md index b4faae9e0e..0b41c7b50d 100644 --- a/docs/extending-caches.md +++ b/docs/extending-caches.md @@ -39,7 +39,7 @@ end ``` ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. Caching can be configured by modifying the [`config/cache.yml`][] file in the buildpack fork. diff --git a/docs/extending-logging.md b/docs/extending-logging.md index 055554f835..a8f7a26241 100644 --- a/docs/extending-logging.md +++ b/docs/extending-logging.md @@ -24,7 +24,7 @@ logger.debug { "#{costly_method}" } ``` ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The console logging severity filter is set to `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL` using the following strategies in descending priority: diff --git a/docs/extending-repositories.md b/docs/extending-repositories.md index 6942b0c111..d30ecef12c 100644 --- a/docs/extending-repositories.md +++ b/docs/extending-repositories.md @@ -59,7 +59,7 @@ end | `{architecture}` | The architecture of the system as returned by Ruby. The value is typically one of `x86_64` or `x86`. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. Repositories can be configured by modifying the [`config/repository.yml`][] file in the buildpack fork. diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index e1f8af624a..337b0df05a 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -29,7 +29,7 @@ When binding AppDynamics using a user-provided service, it must have name or tag To provide more complex values such as the `tier-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `tier-name` could be set with a value of `Tier-$(expr "$VCAP_APPLICATION" : '.*instance_index[": ]*\([[:digit:]]*\).*')` to calculate a value from the Cloud Foundry instance index. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/app_dynamics_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-dyna_trace_agent.md b/docs/framework-dyna_trace_agent.md index f6603a9028..9af9a904e2 100644 --- a/docs/framework-dyna_trace_agent.md +++ b/docs/framework-dyna_trace_agent.md @@ -58,7 +58,7 @@ TIP: Changes will not apply to existing running applications until they are rest ``` ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/dyna_trace_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-introscope_agent.md b/docs/framework-introscope_agent.md index 1b82225903..ee94e6848c 100644 --- a/docs/framework-introscope_agent.md +++ b/docs/framework-introscope_agent.md @@ -31,7 +31,7 @@ The credential payload of the service may contain the following entries: To provide more complex values such as the `agent-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `agent-name` could be set with a value of `agent-$(expr "$VCAP_APPLICATION" : '.*application_name[": ]*\([[:word:]]*\).*')` to calculate a value from the Cloud Foundry application name. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/introscope_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-java_opts.md b/docs/framework-java_opts.md index 24527e42e7..e6334aec48 100644 --- a/docs/framework-java_opts.md +++ b/docs/framework-java_opts.md @@ -16,7 +16,7 @@ Tags are printed to standard output by the buildpack detect script ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by creating or modifying the [`config/java_opts.yml`][] file in the buildpack fork. diff --git a/docs/framework-jrebel_agent.md b/docs/framework-jrebel_agent.md index 38f95550ab..6b60a9f955 100644 --- a/docs/framework-jrebel_agent.md +++ b/docs/framework-jrebel_agent.md @@ -17,7 +17,7 @@ Tags are printed to standard output by the buildpack detect script For more information regarding setup and configuration, please refer to the [JRebel with Pivotal Cloud Foundry tutorial][pivotal]. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/jrebel_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md index da0a6aa845..247164acf4 100644 --- a/docs/framework-luna_security_provider.md +++ b/docs/framework-luna_security_provider.md @@ -27,7 +27,7 @@ When binding to the Luna Security Provider using a user-provided service, it mus To provide more complex values such as the PEM certificates, using the interactive mode when creating a user-provided service will manage the character escaping automatically. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/luna_security_provider.yml`][] file in the buildpack. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-maria_db_jdbc.md b/docs/framework-maria_db_jdbc.md index cd90ced0f9..5e146253a8 100644 --- a/docs/framework-maria_db_jdbc.md +++ b/docs/framework-maria_db_jdbc.md @@ -24,7 +24,7 @@ Tags are printed to standard output by the buildpack detect script Users may optionally provide their own MariaDB or MySQL service. A user-provided MariaDB or MySQL service must have a name or tag with `mariadb` or `mysql` in it so that the MariaDB JDBC Framework will automatically download the JDBC driver JAR and place it on the classpath. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/maria_db_jdbc.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-new_relic_agent.md b/docs/framework-new_relic_agent.md index 9caf545bf0..26f2810e0f 100644 --- a/docs/framework-new_relic_agent.md +++ b/docs/framework-new_relic_agent.md @@ -28,7 +28,7 @@ The credential payload of the service may contain the following entries: | `***` | (Optional) Any additional entries will be applied as a system property appended to `-Dnewrelic.config.` to allow full configuration of the agent. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/new_relic_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-play_framework_auto_reconfiguration.md b/docs/framework-play_framework_auto_reconfiguration.md index a56a5d2b55..04efd16d9a 100644 --- a/docs/framework-play_framework_auto_reconfiguration.md +++ b/docs/framework-play_framework_auto_reconfiguration.md @@ -14,7 +14,7 @@ The Play Framework Auto-reconfiguration Framework causes an application to be au Tags are printed to standard output by the buildpack detect script ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/play_framework_auto_reconfiguration.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-play_framework_jpa_plugin.md b/docs/framework-play_framework_jpa_plugin.md index f5ab7331fa..ed7b0de4bb 100644 --- a/docs/framework-play_framework_jpa_plugin.md +++ b/docs/framework-play_framework_jpa_plugin.md @@ -19,7 +19,7 @@ The Play Framework JPA Plugin Framework causes an application to be automaticall Tags are printed to standard output by the buildpack detect script ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/play_framework_jpa_plugin.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-postgresql_jdbc.md b/docs/framework-postgresql_jdbc.md index 17352ecabf..bff4a17844 100644 --- a/docs/framework-postgresql_jdbc.md +++ b/docs/framework-postgresql_jdbc.md @@ -22,7 +22,7 @@ Tags are printed to standard output by the buildpack detect script Users may optionally provide their own PostgreSQL service. A user-provided PostgreSQL service must have a name or tag with `postgres` in it so that the PostgreSQL JDBC Framework will automatically download the JDBC driver JAR and place it on the classpath. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/postgresql_jdbc.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/framework-spring_auto_reconfiguration.md b/docs/framework-spring_auto_reconfiguration.md index 86b0708e65..bd737a8503 100644 --- a/docs/framework-spring_auto_reconfiguration.md +++ b/docs/framework-spring_auto_reconfiguration.md @@ -16,7 +16,7 @@ Tags are printed to standard output by the buildpack detect script If a `/WEB-INF/web.xml` file exists, the framework will modify it in addition to making the auto-reconfiguration JAR available on the classpath. This modification consists of adding `org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer`, `org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer`, and `org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer` to the collection of `contextInitializerClasses`. The Spring Auto-reconfiguration Framework also adds the `cloud` profile to any existing Spring profiles such as those defined in the [`SPRING_PROFILES_ACTIVE`][] environment variable. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The framework can be configured by modifying the [`config/spring_auto_reconfiguration.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index e335503326..6b6f83bbd9 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -14,7 +14,7 @@ The OpenJDK JRE provides Java runtimes from the [OpenJDK][] project. Versions o Tags are printed to standard output by the buildpack detect script ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index bc2e5121bd..b7271aa5ab 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -23,7 +23,7 @@ Tags are printed to standard output by the buildpack detect script For details on the repository structure, see the [repository documentation][repositories]. ## Configuration -For general information on configuring the buildpack, refer to [Configuration and Extension][]. +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. The JRE can be configured by modifying the [`config/oracle_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. From d95d940907bd0498c4ef8da1bfddd2c095f3d608 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 24 Sep 2015 17:25:48 +0100 Subject: [PATCH 082/812] Better escaping of Java options This commit makes it possible to use both escaped and unescaped $ and \ characters in the value of a Java option. The $ character is required so users can include environment variables in Java options. The \ character is required so it's possible to include an escaped $ charecter in the value of a Java option. [#100119572] --- docs/framework-java_opts.md | 32 +++++++++++++- lib/java_buildpack/framework/java_opts.rb | 12 +++++- .../framework/java_opts_spec.rb | 43 ++++++++++++++++--- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/docs/framework-java_opts.md b/docs/framework-java_opts.md index e6334aec48..2ecac96fda 100644 --- a/docs/framework-java_opts.md +++ b/docs/framework-java_opts.md @@ -14,7 +14,6 @@ The Java Options Framework contributes arbitrary Java options to the application
Detection CriterionExistence of a single bound AppDynamics service. The existence of an AppDynamics service defined by the VCAP_SERVICES payload containing a service name, label or tag with app-dynamics as a substring. + Detection CriterionExistence of a single bound AppDynamics service. The existence of an AppDynamics service defined by the VCAP_SERVICES payload containing a service name, label or tag with app-dynamics or appdynamics as a substring.
Tags are printed to standard output by the buildpack detect script - ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. @@ -29,6 +28,37 @@ Any `JAVA_OPTS` from either the config file or environment variables that config Any `JAVA_OPTS` from either the config file or environment variables will be specified in the start command after any Java Opts added by other frameworks. +## Escaping strings + +Java options will have special characters escaped when used in the shell command that starts the Java application but the `$` and `\` characters will not be escaped. This is to allow Java options to include environment variables when the application starts. + +```bash +cf set-env my-application JAVA_OPTS '-Dexample.port=$PORT' +``` + +If an escaped `$` or `\` character is needed in the Java options they will have to be escaped manually. For example, to obtain this output in the start command. + +```bash +-Dexample.other=something.\$dollar.\\slash +``` + +From the command line use; +```bash +cf set-env my-application JAVA_OPTS '-Dexample.other=something.\\\\\$dollar.\\\\\\\slash' +``` + +From the [`config/java_opts.yml`][] file use; +```yaml +from_environment: true +java_opts: '-Dexample.other=something.\\$dollar.\\\\slash' +``` + +Finally, from the applications manifest use; +```yaml + env: + JAVA_OPTS: '-Dexample.other=something.\\\\\$dollar.\\\\\\\slash' +``` + ## Example ```yaml # JAVA_OPTS configuration diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index 6140635b05..c71948f4d5 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -66,14 +66,22 @@ def parsed_java_opts parsed_java_opts.concat ENV[ENVIRONMENT_VARIABLE].shellsplit if supports_environment? parsed_java_opts.map do |java_opt| - if /(?.+)=(?.+)/ =~ java_opt - "#{key}=#{value.shellescape}" + if /(?.+?)=(?.+)/ =~ java_opt + "#{key}=#{parse_shell_string(value)}" else java_opt end end end + def parse_shell_string(str) + return "''" if str.empty? + str = str.dup + str.gsub!(%r{([^A-Za-z0-9_\-.,:\/@\n$\\])}, '\\\\\\1') + str.gsub!(/\n/, "'\n'") + str + end + def supports_configuration? @configuration.key?(CONFIGURATION_PROPERTY) && !@configuration[CONFIGURATION_PROPERTY].nil? end diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index 69a326e926..548bdea24a 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -66,35 +66,64 @@ it 'adds split java_opts to context' do component.release - expect(java_opts).to include('-Xdebug') expect(java_opts).to include('-Xnoagent') - expect(java_opts).to include('-Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=y') + expect(java_opts).to include('-Xrunjdwp:transport=dt_socket,server\=y,address\=8000,suspend\=y') expect(java_opts).to include('-XX:OnOutOfMemoryError=kill\ -9\ \%p') end end context do let(:configuration) do - { 'java_opts' => '-Dtest=!£$%^&*(){}<>[];~`' } + { 'java_opts' => '-Dtest=!£%^&*()<>[]{};~`' } end it 'escapes special characters' do component.release + expect(java_opts).to include('-Dtest=\!\£\%\^\&\*\(\)\<\>\[\]\{\}\;\~\`') + end + end + + context do + let(:configuration) do + { 'java_opts' => '-Dtest=$DOLLAR\\\SLASH' } + end + + it 'does not escape the shell variable character from configuration' do + component.release + expect(java_opts).to include('-Dtest=$DOLLAR\SLASH') + end + end - expect(java_opts).to include('-Dtest=\\!\\£\\$\\%\\^\\&\\*\\(\\)\\{\\}\\<\\>\\[\\]\\;\\~\\`') + context do + let(:configuration) { { 'from_environment' => true } } + let(:environment) { { 'JAVA_OPTS' => '-Dtest=$dollar\\\slash' } } + + it 'does not escape the shell variable character from environment' do + component.release + expect(java_opts).to include('-Dtest=$dollar\slash') end end context do let(:configuration) do - { 'java_opts' => '-javaagent:agent.jar=port="\$PORT",host=localhost' } + { 'java_opts' => '-Dtest=something.\\\$dollar.\\\\\\\slash' } end - it 'allows escaped characters' do + it 'can escape non-escaped characters ' do component.release + expect(java_opts).to include('-Dtest=something.\\$dollar.\\\slash') + end + end - expect(java_opts).to include('-javaagent:agent.jar=port=$PORT,host=localhost') + context do + let(:configuration) do + { 'java_opts' => '-javaagent:agent.jar=port=$PORT,host=localhost' } + end + + it 'escapes equal signs after the first one' do + component.release + expect(java_opts).to include('-javaagent:agent.jar=port\\=$PORT,host\\=localhost') end end From f20749099750b441ebb18e79e3b8a07a7e61f45b Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Fri, 25 Sep 2015 18:25:21 +0100 Subject: [PATCH 083/812] Document the minimum Xss requirement As described in the GitHub issue, this commit adds documentation about the minimum stack value that may prevent JRE startup. This will only occur should the use edit the default configuration. Close #228 [#103782484] --- docs/jre-open_jdk_jre.md | 4 +++- docs/jre-oracle_jre.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 6b6f83bbd9..13d8157bd4 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -38,7 +38,9 @@ To add custom SSL certificates, add your `cacerts` file to `resources/open_jdk_j ### Memory The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials` and/or `stack_threads` mappings. -Note: if the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. +Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. + +Note: If setting an initial Stack size, depending on the version of Java and the operating system used by Cloud Foundry the JRE will require a minimum `-Xss` value. This tends to be between `100k` and `250k`. #### Memory Sizes The following optional properties may be specified in the `memory_sizes` mapping. diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index b7271aa5ab..7441af9657 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -46,7 +46,9 @@ To add custom SSL certificates, add your `cacerts` file to `resources/oracle_jre ### Memory The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials` and/or `stack_threads` mappings. -Note: if the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. +Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. + +Note: If setting an initial Stack size, depending on the version of Java and the operating system used by Cloud Foundry the JRE will require a minimum `-Xss` value. This tends to be between `100k` and `250k`. #### Memory Sizes The following optional properties may be specified in the `memory_sizes` mapping. From 96c4616d3e4a00fee4c9b291b4a563741ebb12ab Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 1 Oct 2015 10:07:17 -0700 Subject: [PATCH 084/812] Correct VCAP_ Parsing Previously the contents of the VCAP_APPLICATION and VCAP_SERVICES environment variables were parsed as if they were YAML. It would appear that YAML flow syntax is an extremely close approximation of JSON and therefore the parser worked properly. It was recently discovered on a new system that there are cases where YAML flow and JSON diverge causing the parsing to fail. This change fixes the parsing to use JSON as it should have. --- lib/java_buildpack/component/application.rb | 4 ++-- spec/application_helper.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index d483d5d644..efdd8e5db0 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -17,7 +17,7 @@ require 'java_buildpack/component' require 'java_buildpack/component/services' require 'java_buildpack/util/filtering_pathname' -require 'yaml' +require 'json' module JavaBuildpack module Component @@ -68,7 +68,7 @@ def children(root, s = Set.new) end def parse(input) - input ? YAML.load(input) : {} + input ? JSON.load(input) : {} end end diff --git a/spec/application_helper.rb b/spec/application_helper.rb index 439a968587..6d1ec93e9c 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -17,7 +17,7 @@ require 'spec_helper' require 'java_buildpack/component/application' require 'java_buildpack/component/services' -require 'yaml' +require 'json' shared_context 'application_helper' do @@ -26,8 +26,8 @@ previous_environment = ENV.to_hash let(:environment) do - { 'test-key' => 'test-value', 'VCAP_APPLICATION' => vcap_application.to_yaml, - 'VCAP_SERVICES' => vcap_services.to_yaml } + { 'test-key' => 'test-value', 'VCAP_APPLICATION' => vcap_application.to_json, + 'VCAP_SERVICES' => vcap_services.to_json } end before do From 6e530398f55a304bff45722a6c90a21e213d2c0c Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 1 Oct 2015 18:37:18 +0100 Subject: [PATCH 085/812] [#104558394]Configuration for the DynaTrace agent name The commit allows users to set a default agent name in the configuration for DynaTrace. Closes #234 [#104558394] --- config/dyna_trace_agent.yml | 1 + docs/framework-dyna_trace_agent.md | 1 + .../framework/dyna_trace_agent.rb | 2 +- .../framework/dyna_trace_agent_spec.rb | 24 +++++++++++++++---- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/config/dyna_trace_agent.yml b/config/dyna_trace_agent.yml index 84293020d8..a0217e8a2f 100644 --- a/config/dyna_trace_agent.yml +++ b/config/dyna_trace_agent.yml @@ -17,3 +17,4 @@ --- version: 6.1.0_+ repository_root: "" +default_agent_name: diff --git a/docs/framework-dyna_trace_agent.md b/docs/framework-dyna_trace_agent.md index 9af9a904e2..1f6b438ee9 100644 --- a/docs/framework-dyna_trace_agent.md +++ b/docs/framework-dyna_trace_agent.md @@ -66,6 +66,7 @@ The framework can be configured by modifying the [`config/dyna_trace_agent.yml`] | ---- | ----------- | `repository_root` | The URL of the DynaTrace repository index ([details][repositories]). | `version` | The version of DynaTrace to use. This buildpack framework has been tested on 6.1.0. +| `default_agent_name` | This is omitted by default but can be added to set the DynaTrace agent name. If it is not specified then `#{application_name}_#{profile_name}` is used, where `application_name` is defined by Cloud Foundry. ### Additional Resources The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/dyna_trace_agent` directory in the buildpack fork. diff --git a/lib/java_buildpack/framework/dyna_trace_agent.rb b/lib/java_buildpack/framework/dyna_trace_agent.rb index a6e311a1ff..912f0ff400 100644 --- a/lib/java_buildpack/framework/dyna_trace_agent.rb +++ b/lib/java_buildpack/framework/dyna_trace_agent.rb @@ -59,7 +59,7 @@ def agent_path end def agent_name - "#{@application.details['application_name']}_#{profile_name}" + @configuration['default_agent_name'] || "#{@application.details['application_name']}_#{profile_name}" end def architecture diff --git a/spec/java_buildpack/framework/dyna_trace_agent_spec.rb b/spec/java_buildpack/framework/dyna_trace_agent_spec.rb index 24768810f6..f8252f29f7 100644 --- a/spec/java_buildpack/framework/dyna_trace_agent_spec.rb +++ b/spec/java_buildpack/framework/dyna_trace_agent_spec.rb @@ -21,6 +21,10 @@ describe JavaBuildpack::Framework::DynaTraceAgent do include_context 'component_helper' + let(:configuration) do + { 'default_agent_name' => nil } + end + it 'does not detect without dynatrace-n/a service' do expect(component.detect).to be_nil end @@ -45,23 +49,33 @@ it 'updates JAVA_OPTS' do component.release - expect(java_opts).to include( - '-agentpath:$PWD/.java-buildpack/dyna_trace_agent/agent/lib64/'\ + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dyna_trace_agent/agent/lib64/'\ 'libdtagent.so=name=test-application-name_Monitoring,server=test-host-name') end + + context do + + let(:configuration) { { 'default_agent_name' => 'different-agent-name' } } + + it 'updates JAVA_OPTS with configured agent name' do + component.release + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dyna_trace_agent/agent/lib64/'\ + 'libdtagent.so=name=different-agent-name,server=test-host-name') + end + + end end context do before do allow(services).to receive(:one_service?).with(/dynatrace/, 'server').and_return(true) - allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name', + allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name', 'profile' => 'test-profile' }) end it 'updates JAVA_OPTS with custom profile' do component.release - expect(java_opts).to include( - '-agentpath:$PWD/.java-buildpack/dyna_trace_agent/agent/lib64/'\ + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dyna_trace_agent/agent/lib64/'\ 'libdtagent.so=name=test-application-name_test-profile,server=test-host-name') end From 529d1098a075f54af4b958103285a6c0a273df0e Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 30 Sep 2015 14:26:05 -0700 Subject: [PATCH 086/812] Luna Security Provider HA Support Previously the Luna Security Provider only supported a single server configuration. This change updates the framework to support HA-style configuration with multiple servers and virtual token groups. [#104557654] --- docs/framework-luna_security_provider.md | 68 ++++++++++- .../framework/luna_security_provider.rb | 108 +++++++++++++----- .../luna_security_provider/Chrystoki.conf | 31 ++--- .../Chrystoki.conf | 52 +++++++++ .../client-certificate.pem | 3 + .../client-private-key.pem | 3 + .../server-certificates.pem | 6 + .../framework/luna_security_provider_spec.rb | 62 ++++++---- 8 files changed, 259 insertions(+), 74 deletions(-) create mode 100644 spec/fixtures/framework_luna_security_provider/Chrystoki.conf create mode 100644 spec/fixtures/framework_luna_security_provider/client-certificate.pem create mode 100644 spec/fixtures/framework_luna_security_provider/client-private-key.pem create mode 100644 spec/fixtures/framework_luna_security_provider/server-certificates.pem diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md index 247164acf4..ab4106cb2a 100644 --- a/docs/framework-luna_security_provider.md +++ b/docs/framework-luna_security_provider.md @@ -19,12 +19,70 @@ When binding to the Luna Security Provider using a user-provided service, it mus | Name | Description | ---- | ----------- -| `host` | The controller host name -| `host-certificate` | A PEM encoded host certificate -| `client-private-key` | A PEM encoded client private key -| `client-certificate` | A PEM encoded client certificate +| `client` | A hash containing client configuration +| `servers` | An array of hashes containing server configuration +| `groups` | An array of hashes containing group configuration -To provide more complex values such as the PEM certificates, using the interactive mode when creating a user-provided service will manage the character escaping automatically. +#### Client Configuration +| Name | Description +| ---- | ----------- +| `certificate` | A PEM encoded client certificate +| `private-key` | A PEM encoded client private key + +#### Server Configuration +| Name | Description +| ---- | ----------- +| `certificate` | A PEM encoded server certificate +| `name` | A host name or address + +#### Group Configuration +| Name | Description +| ---- | ----------- +| `label` | The label for the group +| `members` | An array of group member serial numbers + +### Example Credentials Payload +``` +{ + "client": { + "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----", + "private-key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----" + }, + "servers": [ + { + "name": "test-host-1", + "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" + }, + { + "name": "test-host-2", + "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" + } + ], + "groups": [ + { + "label": "test-group-1", + "members": [ + "test-serial-number-1", + "test-serial-number-2" + ] + }, + { + "label": "test-group-2", + "members": [ + "test-serial-number-3", + "test-serial-number-4" + ] + } + ] +} +``` + +### Creating Credential Payload +In order to create the credentials payload, you should collapse the JSON payload to a single line and set it like the following + +``` +$ cf create-user-provided-service luna -p '{"client":{"certificate":"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----","private-key":"-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"},"servers":[{"name":"test-host-1","certificate":"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"},{"name":"test-host-2","certificate":"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"}],"groups":[{"label":"test-group-1","members":["test-serial-number-1","test-serial-number-2"]},{"label":"test-group-2","members":["test-serial-number-3","test-serial-number-4"]}]}' +``` ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 435fc0d5dd..26f261442d 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -32,10 +32,9 @@ def compile @droplet.copy_resources credentials = @application.services.find_service(FILTER)['credentials'] - write_host_certificate credentials - write_client_certificate credentials - write_client_private_key credentials - write_host credentials + write_client credentials['client'] + write_servers credentials['servers'] + write_configuration credentials['servers'], credentials['groups'] end # (see JavaBuildpack::Component::BaseComponent#release) @@ -51,8 +50,7 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, 'host', 'host-certificate', 'client-private-key', - 'client-certificate' + @application.services.one_service? FILTER, 'client', 'servers', 'groups' end private @@ -66,11 +64,11 @@ def chrystoki end def client_certificate - @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameCert.pem' + @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem' end def client_private_key - @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameKey.pem' + @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-private-key.pem' end def expand(file) @@ -91,10 +89,6 @@ def ext_dirs "#{qualify_path(@droplet.sandbox + 'usr/safenet/lunaclient/jsp/lib', @droplet.root)}" end - def host_certificate - @droplet.sandbox + 'usr/safenet/lunaclient/cert/server/CAFile.pem' - end - def install_client(root) FileUtils.mkdir_p @droplet.sandbox @@ -112,37 +106,95 @@ def lunajsp(root) Dir[root + 'lunajsp-*.x86_64.rpm'][0] end + def padded_index(index) + index.to_s.rjust(2, '0') + end + + def relative(path) + path.relative_path_from(@droplet.root) + end + def rpm2cpio Pathname.new(File.expand_path('../rpm2cpio.py', __FILE__)) end - def write_client_certificate(credentials) - FileUtils.mkdir_p client_certificate.parent - client_certificate.open(File::CREAT | File::WRONLY) { |f| f.write credentials['client-certificate'] } + def server_certificates + @droplet.sandbox + 'usr/safenet/lunaclient/cert/server/server-certificates.pem' end - def write_client_private_key(credentials) + def write_client(client) + FileUtils.mkdir_p client_certificate.parent + client_certificate.open(File::CREAT | File::WRONLY) do |f| + f.write "#{client['certificate']}\n" + end + FileUtils.mkdir_p client_private_key.parent - client_private_key.open(File::CREAT | File::WRONLY) { |f| f.write credentials['client-private-key'] } + client_private_key.open(File::CREAT | File::WRONLY) do |f| + f.write "#{client['private-key']}\n" + end + end + + def write_configuration(servers, groups) + chrystoki.open(File::APPEND | File::WRONLY) do |f| + write_prologue f + servers.each_with_index { |server, index| write_server f, index, server } + f.write < { 'server' => 'test-server', - 'host' => 'test-host', - 'host-certificate' => 'test-host-cert', - 'client-private-key' => 'test-private-key', - 'client-certificate' => 'test-client-cert' }) + .and_return('credentials' => { + 'client' => { + 'certificate' => "-----BEGIN CERTIFICATE-----\n" \ + "test-client-cert\n-----END CERTIFICATE-----", + 'private-key' => "-----BEGIN RSA PRIVATE KEY-----\n" \ + "test-client-private-key\n-----END RSA PRIVATE KEY-----" + }, + 'servers' => [ + { + 'name' => 'test-server-1', + 'certificate' => "-----BEGIN CERTIFICATE-----\n" \ + "test-server-1-cert\n-----END CERTIFICATE-----" + }, { + 'name' => 'test-server-2', + 'certificate' => "-----BEGIN CERTIFICATE-----\n" \ + "test-server-2-cert\n-----END CERTIFICATE-----" + }], + 'groups' => [ + { + 'label' => 'test-group-1', + 'members' => %w(test-group-1-member-1 test-group-1-member-2) + }, { + 'label' => 'test-group-2', + 'members' => %w(test-group-2-member-1 test-group-2-member-2) + } + ] }) end it 'detects with luna-n/a service' do @@ -68,21 +86,25 @@ component.compile - expect(sandbox + 'usr/safenet/lunaclient/cert/server/CAFile.pem').to exist - expect(sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameCert.pem').to exist - expect(sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameKey.pem').to exist + expect(sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem').to exist + expect(sandbox + 'usr/safenet/lunaclient/cert/client/client-private-key.pem').to exist + expect(sandbox + 'usr/safenet/lunaclient/cert/server/server-certificates.pem').to exist - check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/server/CAFile.pem', 'test-host-cert') - check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameCert.pem', 'test-client-cert') - check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/client/ClientNameKey.pem', 'test-private-key') + check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem', + 'spec/fixtures/framework_luna_security_provider/client-certificate.pem') + check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/client/client-private-key.pem', + 'spec/fixtures/framework_luna_security_provider/client-private-key.pem') + check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/server/server-certificates.pem', + 'spec/fixtures/framework_luna_security_provider/server-certificates.pem') end - it 'writes host information', + it 'writes configuration', cache_fixture: 'stub-luna-security-provider.tar' do component.compile - expect(File.read(sandbox + 'Chrystoki.conf')).to include('ServerName00 = test-host') + expect(sandbox + 'Chrystoki.conf').to exist + check_file_contents(sandbox + 'Chrystoki.conf', 'spec/fixtures/framework_luna_security_provider/Chrystoki.conf') end it 'updates environment variables' do @@ -98,8 +120,8 @@ 'luna_security_provider/usr/safenet/lunaclient/jsp/lib') end - def check_file_contents(file, contents) - expect(File.read(file)).to eq contents + def check_file_contents(actual, expected) + expect(File.read(actual)).to eq File.read(expected) end end From 4703e4d970fe7fc68b8074228304968665a08287 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Mon, 12 Oct 2015 16:23:52 +0100 Subject: [PATCH 087/812] Update environment variable config style It is possible to specify environment variables that update the buildpack configuration using both [...] and {...} styles, the buildpack will handle both. Previously the documentation recommended the [...] approach. This commit changes the documentation and tests to use the {...} style. No changes have been made to the implementation and both [...] and {...} styles are still valid. [close #237] --- README.md | 17 ++++++++++++----- .../util/configuration_utils_spec.rb | 12 ++++++------ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 438cf75651..ec529f9da3 100644 --- a/README.md +++ b/README.md @@ -27,30 +27,36 @@ The following are _very_ simple examples for deploying the artifact types that w ## Configuration and Extension The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. -Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec. For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. +Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec ([Wikipedia] has a good description of this yaml syntax). For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. ```bash -$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '[jre: { version: 1.7.0_+ }]' +$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{jre: { version: 1.7.0_+ }}' ``` If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. ```bash -$ cf set-env my-application JBP_CONFIG_REPOSITORY '[default_repository_root: "http://repo.example.io"]' +$ cf set-env my-application JBP_CONFIG_REPOSITORY '{default_repository_root: "http://repo.example.io"}' +``` + +If the key or value contains an environment variable that you want to bind at runtime you need to escape it from your shell. For example, to add command line arguments containing an environment variable to a [Java Main](docs/container-java_main.md) application. + +```bash +$ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{arguments: "-server.port=\$PORT -foo=bar"}' ``` Environment variable can also be specified in the applications `manifest` file. For example, to specify an environment variable in an applications manifest file that disables Auto-reconfiguration. ```bash env: - JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '[enabled: false]' + JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}' ``` This final example shows how to change the version of Tomcat that is used by the buildpack with an environment variable specified in the applications manifest file. ```bash env: - JBP_CONFIG_TOMCAT: '[tomcat: { version: 8.0.+ }]' + JBP_CONFIG_TOMCAT: '{tomcat: { version: 8.0.+ }}' ``` See the [Environment Variables][] documentation for more information. @@ -168,3 +174,4 @@ This buildpack is released under version 2.0 of the [Apache License][]. [Pull requests]: http://help.github.com/send-pull-requests [Running Cloud Foundry locally]: http://docs.cloudfoundry.org/deploying/run-local.html [Spring Boot]: http://projects.spring.io/spring-boot/ +[Wikipedia]: https://en.wikipedia.org/wiki/YAML#Basic_components_of_YAML \ No newline at end of file diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index bcfaa74175..6c59a1e537 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -59,15 +59,15 @@ end it 'load configuration file and clean nil values' do - expect(described_class.load('test', true)).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, - 'version' => '1.7.1') + expect(described_class.load('test', true)).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.7.1') end context do let(:environment) do - { 'JBP_CONFIG_TEST' => '[bar: {alpha: {one: 3, two: {one: 3}}, bravo: newValue}, foo: lion]' } + { 'JBP_CONFIG_TEST' => '{bar: {alpha: {one: 3, two: {one: 3}}, bravo: newValue}, foo: lion}' } end it 'overlays matching environment variables' do @@ -82,7 +82,7 @@ context do let(:environment) do - { 'JBP_CONFIG_TEST' => 'version: 1.8.+' } + { 'JBP_CONFIG_TEST' => '{version: 1.8.+}' } end it 'overlays simple matching environment variable' do @@ -96,7 +96,7 @@ context do let(:environment) do - { 'JBP_CONFIG_TEST' => 'version 1.8.+' } + { 'JBP_CONFIG_TEST' => 'Not an array or a hash' } end it 'raises an exception when invalid override value is specified' do From b533b6c8caf53ff20d749e84860496ef4bcd85b9 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 16 Oct 2015 17:38:08 -0700 Subject: [PATCH 088/812] Debug Framework This change adds a framework that contributes Java debug configuration to an application. Note that this is only useful in Diego-based containers with SSH access enabled. [#105552412] --- .idea/dictionaries/bhale.xml | 1 + README.md | 9 +-- config/components.yml | 3 +- config/debug.yml | 20 +++++++ docs/framework-debug.md | 28 +++++++++ lib/java_buildpack/framework/debug.rb | 62 ++++++++++++++++++++ spec/java_buildpack/framework/debug_spec.rb | 64 +++++++++++++++++++++ 7 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 config/debug.yml create mode 100644 docs/framework-debug.md create mode 100644 lib/java_buildpack/framework/debug.rb create mode 100644 spec/java_buildpack/framework/debug_spec.rb diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 2a83fa8ef8..1203ffc23a 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -31,6 +31,7 @@ isengard javaagent jdk's + jrebel jres jsome jtest diff --git a/README.md b/README.md index ec529f9da3..b0437567d8 100644 --- a/README.md +++ b/README.md @@ -48,14 +48,14 @@ $ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{arguments: "-server.port=\$PO Environment variable can also be specified in the applications `manifest` file. For example, to specify an environment variable in an applications manifest file that disables Auto-reconfiguration. ```bash - env: + env: JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}' ``` This final example shows how to change the version of Tomcat that is used by the buildpack with an environment variable specified in the applications manifest file. ```bash - env: + env: JBP_CONFIG_TOMCAT: '{tomcat: { version: 8.0.+ }}' ``` @@ -77,8 +77,9 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) - * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) + * [Debug](docs/framework-debug.md) ([Configuration](docs/debug.md#configuration)) * [DynaTrace Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) + * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) @@ -174,4 +175,4 @@ This buildpack is released under version 2.0 of the [Apache License][]. [Pull requests]: http://help.github.com/send-pull-requests [Running Cloud Foundry locally]: http://docs.cloudfoundry.org/deploying/run-local.html [Spring Boot]: http://projects.spring.io/spring-boot/ -[Wikipedia]: https://en.wikipedia.org/wiki/YAML#Basic_components_of_YAML \ No newline at end of file +[Wikipedia]: https://en.wikipedia.org/wiki/YAML#Basic_components_of_YAML diff --git a/config/components.yml b/config/components.yml index b63de955d3..0c9048e74c 100644 --- a/config/components.yml +++ b/config/components.yml @@ -36,8 +36,9 @@ jres: frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" -# - "JavaBuildpack::Framework::IntroscopeAgent" + - "JavaBuildpack::Framework::Debug" # - "JavaBuildpack::Framework::DynaTraceAgent" +# - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::JrebelAgent" # - "JavaBuildpack::Framework::LunaSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" diff --git a/config/debug.yml b/config/debug.yml new file mode 100644 index 0000000000..7672ef22d4 --- /dev/null +++ b/config/debug.yml @@ -0,0 +1,20 @@ +# Cloud Foundry Java Buildpack +# Copyright 2014-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Debug configuration +--- +enabled: false +port: 8000 +suspend: false diff --git a/docs/framework-debug.md b/docs/framework-debug.md new file mode 100644 index 0000000000..5a8dab57b1 --- /dev/null +++ b/docs/framework-debug.md @@ -0,0 +1,28 @@ +# Debug Framework +The Debug Framework contributes Java debug configuration to the application at runtime. **Note:** This framework is only useful in Diego-based containers with SSH access enabled. + + + + + + + + + + +
Detection Criterionenabled set in the config/debug.yml file
Tagsdebug
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by creating or modifying the [`config/debug.yml`][] file in the buildpack fork. + +| Name | Description +| ---- | ----------- +| `enabled` | Whether to enable Java debuging +| `port` | The port that the debug agent will listen on +| `suspend` | Whether to suspend execution until a debugger has attached. Note, enabling this may cause application start to timeout and be restarted. + +[`config/debug.yml`]: ../config/debug.yml +[Configuration and Extension]: ../README.md#configuration-and-extension diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb new file mode 100644 index 0000000000..92b3d31e1d --- /dev/null +++ b/lib/java_buildpack/framework/debug.rb @@ -0,0 +1,62 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/base_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/dash_case' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for contributing Java debug options to an application. + class Debug < JavaBuildpack::Component::BaseComponent + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + enabled? ? Debug.to_s.dash_case : nil + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts.add_preformatted_options debug + end + + private + + def debug + "-agentlib:jdwp=transport=dt_socket,server=y,address=#{port},suspend=#{suspend}" + end + + def enabled? + @configuration['enabled'] + end + + def port + @configuration['port'] || 8000 + end + + def suspend + @configuration['suspend'] ? 'y' : 'n' + end + + end + + end +end diff --git a/spec/java_buildpack/framework/debug_spec.rb b/spec/java_buildpack/framework/debug_spec.rb new file mode 100644 index 0000000000..0ca774c9d2 --- /dev/null +++ b/spec/java_buildpack/framework/debug_spec.rb @@ -0,0 +1,64 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/debug' + +describe JavaBuildpack::Framework::Debug do + include_context 'component_helper' + + it 'does not detect if not enabled' do + expect(component.detect).to be_nil + end + + context do + let(:configuration) { { 'enabled' => true } } + + it 'detects when enabled' do + expect(component.detect).to eq('debug') + end + + it 'uses 8000 as the default port' do + component.release + expect(java_opts).to include('-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n') + end + + it 'does not suspend by default' do + component.release + expect(java_opts).to include('-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n') + end + end + + context do + let(:configuration) { { 'enabled' => true, 'port' => 8001 } } + + it 'uses configured port' do + component.release + expect(java_opts).to include('-agentlib:jdwp=transport=dt_socket,server=y,address=8001,suspend=n') + end + end + + context do + let(:configuration) { { 'enabled' => true, 'suspend' => true } } + + it 'uses configured suspend' do + component.release + expect(java_opts).to include('-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=y') + end + end + +end From ae4a73476b091b1b8842a7548be13d67699f82bd Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 4 Nov 2015 10:57:07 -0800 Subject: [PATCH 089/812] Debug SSH Tunnel Documentation This change enhances the Debug framework documentation by adding instructions for creating the required SSH tunnel. --- docs/framework-debug-eclipse.png | Bin 0 -> 335957 bytes docs/framework-debug.md | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 docs/framework-debug-eclipse.png diff --git a/docs/framework-debug-eclipse.png b/docs/framework-debug-eclipse.png new file mode 100644 index 0000000000000000000000000000000000000000..e01c28d329becfc8ab624de1fe047c84e9b0546b GIT binary patch literal 335957 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

dOVT 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

lD6Ft|V?wkeEr=HVBwr_Vc2UzDt6FO_#GX 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 a-u@Mu!lQ($)`%b?3_UGl&3d@w{XYR2_s=l^ literal 0 HcmV?d00001 diff --git a/docs/framework-debug.md b/docs/framework-debug.md index 5a8dab57b1..dd558d536f 100644 --- a/docs/framework-debug.md +++ b/docs/framework-debug.md @@ -21,8 +21,21 @@ The framework can be configured by creating or modifying the [`config/debug.yml` | Name | Description | ---- | ----------- | `enabled` | Whether to enable Java debuging -| `port` | The port that the debug agent will listen on +| `port` | The port that the debug agent will listen on. Defaults to `8000`. | `suspend` | Whether to suspend execution until a debugger has attached. Note, enabling this may cause application start to timeout and be restarted. +## Creating SSH Tunnel +After starting an application with debugging enabled, an SSH tunnel must be created to the container. To create that SSH container, execute the following command: + +```bash +$ cf ssh -N -T -L :localhost: +``` + +The `REMOTE_PORT` should match the `port` configuration for the application (`8000` by default). The `LOCAL_PORT` can be any open port on your computer, but typically matches the `REMOTE_PORT` where possible. + +Once the SSH tunnel has been created, your IDE should connect to `localhost` for debugging. + +![Eclipse Configuration](framework-debug-eclipse.png) + [`config/debug.yml`]: ../config/debug.yml [Configuration and Extension]: ../README.md#configuration-and-extension From 4d561a3d5fd138c5c2201f9ff5005bbe1bf58f59 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 5 Nov 2015 15:46:38 -0800 Subject: [PATCH 090/812] JMX Framework This change adds a framework that contributes JMX configuration to an application. Note that this is only useful in Diego-based containers with SSH access enabled. [#107537380] --- .idea/dictionaries/bhale.xml | 1 + .idea/encodings.xml | 7 ++- README.md | 1 + config/components.yml | 1 + config/jmx.yml | 19 +++++++ docs/framework-debug.md | 4 +- docs/framework-jmx-jconsole.png | Bin 0 -> 77310 bytes docs/framework-jmx.md | 40 ++++++++++++++ lib/java_buildpack/framework/debug.rb | 2 +- lib/java_buildpack/framework/jmx.rb | 58 ++++++++++++++++++++ spec/java_buildpack/framework/debug_spec.rb | 2 +- spec/java_buildpack/framework/jmx_spec.rb | 56 +++++++++++++++++++ 12 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 config/jmx.yml create mode 100644 docs/framework-jmx-jconsole.png create mode 100644 docs/framework-jmx.md create mode 100644 lib/java_buildpack/framework/jmx.rb create mode 100644 spec/java_buildpack/framework/jmx_spec.rb diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 1203ffc23a..57e80b9568 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -31,6 +31,7 @@ isengard javaagent jdk's + jmxremote jrebel jres jsome diff --git a/.idea/encodings.xml b/.idea/encodings.xml index e206d70d85..f758959656 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,5 +1,6 @@ - - - + + + + \ No newline at end of file diff --git a/README.md b/README.md index b0437567d8..e556947a78 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) + * [JMX](docs/framework-jmx.md) ([Configuration](docs/jmx.md#configuration)) * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 0c9048e74c..27aae5bebe 100644 --- a/config/components.yml +++ b/config/components.yml @@ -39,6 +39,7 @@ frameworks: - "JavaBuildpack::Framework::Debug" # - "JavaBuildpack::Framework::DynaTraceAgent" # - "JavaBuildpack::Framework::IntroscopeAgent" + - "JavaBuildpack::Framework::Jmx" - "JavaBuildpack::Framework::JrebelAgent" # - "JavaBuildpack::Framework::LunaSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" diff --git a/config/jmx.yml b/config/jmx.yml new file mode 100644 index 0000000000..bd1eb15988 --- /dev/null +++ b/config/jmx.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2014-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# JMX configuration +--- +enabled: false +port: 5000 diff --git a/docs/framework-debug.md b/docs/framework-debug.md index dd558d536f..522ae99347 100644 --- a/docs/framework-debug.md +++ b/docs/framework-debug.md @@ -8,7 +8,7 @@ The Debug Framework contributes Java debug configuration to the application at r Tags - debug + debug=<port> Tags are printed to standard output by the buildpack detect script @@ -20,7 +20,7 @@ The framework can be configured by creating or modifying the [`config/debug.yml` | Name | Description | ---- | ----------- -| `enabled` | Whether to enable Java debuging +| `enabled` | Whether to enable Java debugging | `port` | The port that the debug agent will listen on. Defaults to `8000`. | `suspend` | Whether to suspend execution until a debugger has attached. Note, enabling this may cause application start to timeout and be restarted. diff --git a/docs/framework-jmx-jconsole.png b/docs/framework-jmx-jconsole.png new file mode 100644 index 0000000000000000000000000000000000000000..ed0a52ebb1584a7dd2d4bf1ee15a315460710bfe GIT binary patch literal 77310 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 KKse#~(|-fkESq)! literal 0 HcmV?d00001 diff --git a/docs/framework-jmx.md b/docs/framework-jmx.md new file mode 100644 index 0000000000..7ef118bb42 --- /dev/null +++ b/docs/framework-jmx.md @@ -0,0 +1,40 @@ +# JMX Framework +The JMX Framework contributes Java JMX configuration to the application at runtime. **Note:** This framework is only useful in Diego-based containers with SSH access enabled. + + + + + + + + + + +
Detection Criterionenabled set in the config/jmx.yml file
Tagsjmx=<port>
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by creating or modifying the [`config/jmx.yml`][] file in the buildpack fork. + +| Name | Description +| ---- | ----------- +| `enabled` | Whether to enable JMX +| `port` | The port that the debug agent will listen on. Defaults to `5000`. + +## Creating SSH Tunnel +After starting an application with JMX enabled, an SSH tunnel must be created to the container. To create that SSH container, execute the following command: + +```bash +$ cf ssh -N -T -L :localhost: +``` + +The `REMOTE_PORT` should match the `port` configuration for the application (`5000` by default). The `LOCAL_PORT` can be any open port on your computer, but typically matches the `REMOTE_PORT` where possible. + +Once the SSH tunnel has been created, your JConsole should connect to `localhost:` for debugging. + +![JConsole Configuration](framework-jmx-jconsole.png) + +[`config/jmx.yml`]: ../config/jmx.yml +[Configuration and Extension]: ../README.md#configuration-and-extension diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index 92b3d31e1d..6f8c9259c4 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -26,7 +26,7 @@ class Debug < JavaBuildpack::Component::BaseComponent # (see JavaBuildpack::Component::BaseComponent#detect) def detect - enabled? ? Debug.to_s.dash_case : nil + enabled? ? "#{Debug.to_s.dash_case}=#{port}" : nil end # (see JavaBuildpack::Component::BaseComponent#compile) diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb new file mode 100644 index 0000000000..02c53bbc16 --- /dev/null +++ b/lib/java_buildpack/framework/jmx.rb @@ -0,0 +1,58 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/base_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/dash_case' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for contributing Java JMX options to an application. + class Jmx < JavaBuildpack::Component::BaseComponent + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + enabled? ? "#{Jmx.to_s.dash_case}=#{port}" : nil + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts + .add_system_property('java.rmi.server.hostname', '127.0.0.1') + .add_system_property('com.sun.management.jmxremote.authenticate', false) + .add_system_property('com.sun.management.jmxremote.port', port) + .add_system_property('com.sun.management.jmxremote.rmi.port', port) + end + + private + + def enabled? + @configuration['enabled'] + end + + def port + @configuration['port'] || 5000 + end + + end + + end +end diff --git a/spec/java_buildpack/framework/debug_spec.rb b/spec/java_buildpack/framework/debug_spec.rb index 0ca774c9d2..f8e40b135d 100644 --- a/spec/java_buildpack/framework/debug_spec.rb +++ b/spec/java_buildpack/framework/debug_spec.rb @@ -29,7 +29,7 @@ let(:configuration) { { 'enabled' => true } } it 'detects when enabled' do - expect(component.detect).to eq('debug') + expect(component.detect).to eq('debug=8000') end it 'uses 8000 as the default port' do diff --git a/spec/java_buildpack/framework/jmx_spec.rb b/spec/java_buildpack/framework/jmx_spec.rb new file mode 100644 index 0000000000..5eff392189 --- /dev/null +++ b/spec/java_buildpack/framework/jmx_spec.rb @@ -0,0 +1,56 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/jmx' + +describe JavaBuildpack::Framework::Jmx do + include_context 'component_helper' + + it 'does not detect if not enabled' do + expect(component.detect).to be_nil + end + + context do + let(:configuration) { { 'enabled' => true } } + + it 'detects when enabled' do + expect(component.detect).to eq('jmx=5000') + end + + it 'uses 5000 as the default port' do + component.release + expect(java_opts).to include '-Djava.rmi.server.hostname=127.0.0.1' + expect(java_opts).to include '-Dcom.sun.management.jmxremote.authenticate=false' + expect(java_opts).to include '-Dcom.sun.management.jmxremote.port=5000' + expect(java_opts).to include '-Dcom.sun.management.jmxremote.rmi.port=5000' + end + end + + context do + let(:configuration) { { 'enabled' => true, 'port' => 5001 } } + + it 'uses configured port' do + component.release + expect(java_opts).to include '-Djava.rmi.server.hostname=127.0.0.1' + expect(java_opts).to include '-Dcom.sun.management.jmxremote.authenticate=false' + expect(java_opts).to include '-Dcom.sun.management.jmxremote.port=5001' + expect(java_opts).to include '-Dcom.sun.management.jmxremote.rmi.port=5001' + end + end + +end From 6c861beacc1dd477eed1bb54c0ee6968cb1744e8 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 5 Nov 2015 16:01:28 -0800 Subject: [PATCH 091/812] JMX RMI Port Fix This change updates the JMX framework to fix a problem where the port number of the JMX RMI server overlapped with the JMX connector port. --- lib/java_buildpack/framework/jmx.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 02c53bbc16..12456c9f8d 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -39,7 +39,7 @@ def release .add_system_property('java.rmi.server.hostname', '127.0.0.1') .add_system_property('com.sun.management.jmxremote.authenticate', false) .add_system_property('com.sun.management.jmxremote.port', port) - .add_system_property('com.sun.management.jmxremote.rmi.port', port) + .add_system_property('com.sun.management.jmxremote.rmi.port', port + 1) end private From e2ad03713a05de5d09b3eba43010f4d2c03d2d67 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 5 Nov 2015 16:09:53 -0800 Subject: [PATCH 092/812] Revert "JMX RMI Port Fix" This reverts commit 6c861beacc1dd477eed1bb54c0ee6968cb1744e8. --- lib/java_buildpack/framework/jmx.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 12456c9f8d..02c53bbc16 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -39,7 +39,7 @@ def release .add_system_property('java.rmi.server.hostname', '127.0.0.1') .add_system_property('com.sun.management.jmxremote.authenticate', false) .add_system_property('com.sun.management.jmxremote.port', port) - .add_system_property('com.sun.management.jmxremote.rmi.port', port + 1) + .add_system_property('com.sun.management.jmxremote.rmi.port', port) end private From c2ef197399bd0defa90ca257ebca93bf639820ff Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 5 Nov 2015 16:11:55 -0800 Subject: [PATCH 093/812] Missing JMX Configuration Parameter This change adds a missing JMX configuration parameter to the JMX Framework. [#107537380] --- lib/java_buildpack/framework/jmx.rb | 1 + spec/java_buildpack/framework/jmx_spec.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 02c53bbc16..efaec43271 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -38,6 +38,7 @@ def release @droplet.java_opts .add_system_property('java.rmi.server.hostname', '127.0.0.1') .add_system_property('com.sun.management.jmxremote.authenticate', false) + .add_system_property('com.sun.management.jmxremote.ssl', false) .add_system_property('com.sun.management.jmxremote.port', port) .add_system_property('com.sun.management.jmxremote.rmi.port', port) end diff --git a/spec/java_buildpack/framework/jmx_spec.rb b/spec/java_buildpack/framework/jmx_spec.rb index 5eff392189..5345afe036 100644 --- a/spec/java_buildpack/framework/jmx_spec.rb +++ b/spec/java_buildpack/framework/jmx_spec.rb @@ -36,6 +36,7 @@ component.release expect(java_opts).to include '-Djava.rmi.server.hostname=127.0.0.1' expect(java_opts).to include '-Dcom.sun.management.jmxremote.authenticate=false' + expect(java_opts).to include '-Dcom.sun.management.jmxremote.ssl=false' expect(java_opts).to include '-Dcom.sun.management.jmxremote.port=5000' expect(java_opts).to include '-Dcom.sun.management.jmxremote.rmi.port=5000' end @@ -48,6 +49,7 @@ component.release expect(java_opts).to include '-Djava.rmi.server.hostname=127.0.0.1' expect(java_opts).to include '-Dcom.sun.management.jmxremote.authenticate=false' + expect(java_opts).to include '-Dcom.sun.management.jmxremote.ssl=false' expect(java_opts).to include '-Dcom.sun.management.jmxremote.port=5001' expect(java_opts).to include '-Dcom.sun.management.jmxremote.rmi.port=5001' end From 3dd61ed876c7d2137a5b8cc596c15646f5514337 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 6 Nov 2015 12:17:55 -0800 Subject: [PATCH 094/812] YourKit Framework This change adds a framework to support the configuration of the YourKit profiler for applications. [#107751904] --- .idea/dictionaries/bhale.xml | 2 + README.md | 5 +- config/components.yml | 1 + config/your_kit_profiler.yml | 22 +++++ docs/framework-your_kit_profiler.md | 48 ++++++++++ docs/framework-your_kit_profiler.png | Bin 0 -> 131512 bytes .../framework/your_kit_profiler.rb | 82 ++++++++++++++++++ spec/fixtures/stub-your-kit-profiler.so | 0 .../framework/your_kit_profiler_spec.rb | 81 +++++++++++++++++ 9 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 config/your_kit_profiler.yml create mode 100644 docs/framework-your_kit_profiler.md create mode 100644 docs/framework-your_kit_profiler.png create mode 100644 lib/java_buildpack/framework/your_kit_profiler.rb create mode 100644 spec/fixtures/stub-your-kit-profiler.so create mode 100644 spec/java_buildpack/framework/your_kit_profiler_spec.rb diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 57e80b9568..3df374525b 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -38,6 +38,7 @@ jtest killjava libcryptoki + libyjpagent ljust lunaclient mainclass @@ -71,6 +72,7 @@ rubocop safenet scriptdir + sessionname shellwords simplecov socketfactory diff --git a/README.md b/README.md index e556947a78..a6c7dfd912 100644 --- a/README.md +++ b/README.md @@ -77,12 +77,12 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) - * [Debug](docs/framework-debug.md) ([Configuration](docs/debug.md#configuration)) + * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) * [DynaTrace Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) - * [JMX](docs/framework-jmx.md) ([Configuration](docs/jmx.md#configuration)) + * [JMX](docs/framework-jmx.md) ([Configuration](docs/framework-jmx.md#configuration)) * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) @@ -91,6 +91,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) * [Spring Insight](docs/framework-spring_insight.md) + * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) * Standard JREs * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) * [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 27aae5bebe..ce1ca296bb 100644 --- a/config/components.yml +++ b/config/components.yml @@ -49,4 +49,5 @@ frameworks: - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" + - "JavaBuildpack::Framework::YourKitProfiler" - "JavaBuildpack::Framework::JavaOpts" diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml new file mode 100644 index 0000000000..d7a9085f8f --- /dev/null +++ b/config/your_kit_profiler.yml @@ -0,0 +1,22 @@ +# Cloud Foundry Java Buildpack +# Copyright 2014-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# JMX configuration +--- +version: 2015.+ +repository_root: ! '{default.repository.root}/your-kit/{platform}/{architecture}' +enabled: false +port: 10001 +default_session_name: ! '$(expr "$VCAP_APPLICATION" : ''.*application_name[": ]*\([-_a-zA-Z0-9]*\).*''):$(expr "$VCAP_APPLICATION" : ''.*instance_index[": ]*\([[:digit:]]*\).*'')' diff --git a/docs/framework-your_kit_profiler.md b/docs/framework-your_kit_profiler.md new file mode 100644 index 0000000000..ab478f2bf6 --- /dev/null +++ b/docs/framework-your_kit_profiler.md @@ -0,0 +1,48 @@ +# YourKit Profiler Framework +The YourKit Profiler Framework contributes YourKit Profielr configuration to the application at runtime. **Note:** This framework is only useful in Diego-based containers with SSH access enabled. + + + + + + + + + + +
Detection Criterionenabled set in the config/your_kit_profiler.yml file
Tagsyour-kit-profiler=<version>
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by creating or modifying the [`config/your_kit_profiler.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `default_session_name` | The session name to display in the YourKit Profiler UI. Defaults to `:`. +| `enabled` | Whether to enable the YourKit Profiler +| `port` | The port that the YourKit Profiler will listen on. Defaults to `10001`. +| `repository_root` | The URL of the YourKit Profiler repository index ([details][repositories]). +| `version` | The version of the YourKit Profiler to use. Candidate versions can be found in the listings for [mountainlion][], [precise][], and [trusty][]. + +## Creating SSH Tunnel +After starting an application with the YourKit Profiler enabled, an SSH tunnel must be created to the container. To create that SSH container, execute the following command: + +```bash +$ cf ssh -N -T -L :localhost: +``` + +The `REMOTE_PORT` should match the `port` configuration for the application (`10001` by default). The `LOCAL_PORT` can be any open port on your computer, but typically matches the `REMOTE_PORT` where possible. + +Once the SSH tunnel has been created, your YourKit Profiler should connect to `localhost:` for debugging. + +![YourKit Configuration](framework-your_kit_profiler.png) + +[`config/your_kit_profiler.yml`]: ../config/your_kit_profiler.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[mountainlion]: http://download.pivotal.io.s3.amazonaws.com/your-kit/mountainlion/x86_64/index.yml +[precise]: http://download.pivotal.io.s3.amazonaws.com/your-kit/precise/x86_64/index.yml +[repositories]: extending-repositories.md +[trusty]: http://download.pivotal.io.s3.amazonaws.com/your-kit/trusty/x86_64/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/framework-your_kit_profiler.png b/docs/framework-your_kit_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..3a036436be822e0edd5dc050ed04678f406601bf GIT binary patch literal 131512 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 snapshots, 'logdir' => logs, + 'port' => port, 'sessionname' => session_name) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @configuration['enabled'] + end + + private + + def file_name + @droplet.sandbox + "#{@droplet.component_id}-#{@version}" + end + + def logs + qualify_path(@droplet.sandbox + 'logs', @droplet.root) + end + + def port + @configuration['port'] || 10_001 + end + + def session_name + @configuration['default_session_name'] || @application.details['application_name'] + end + + def snapshots + qualify_path(@droplet.sandbox + 'snapshots', @droplet.root) + end + + end + + end +end diff --git a/spec/fixtures/stub-your-kit-profiler.so b/spec/fixtures/stub-your-kit-profiler.so new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/your_kit_profiler_spec.rb b/spec/java_buildpack/framework/your_kit_profiler_spec.rb new file mode 100644 index 0000000000..adc4e0be8c --- /dev/null +++ b/spec/java_buildpack/framework/your_kit_profiler_spec.rb @@ -0,0 +1,81 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/your_kit_profiler' + +describe JavaBuildpack::Framework::YourKitProfiler do + include_context 'component_helper' + + it 'does not detect if not enabled' do + expect(component.detect).to be_nil + end + + context do + let(:configuration) { { 'enabled' => true } } + + it 'detects when enabled' do + expect(component.detect).to eq("your-kit-profiler=#{version}") + end + + it 'downloads YourKit agent', + cache_fixture: 'stub-your-kit-profiler.so' do + + component.compile + + expect(sandbox + "your_kit_profiler-#{version}").to exist + end + + context do + it 'updates JAVA_OPTS' do + component.release + + expect(java_opts).to include("-agentpath:$PWD/.java-buildpack/your_kit_profiler/your_kit_profiler-#{version}=" \ + 'dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/your_kit_profiler/logs,' \ + 'port=10001,sessionname=test-application-name') + + end + + context do + let(:configuration) { super().merge 'port' => 10_002 } + + it 'adds port from configuration to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/your_kit_profiler/your_kit_profiler-' \ + "#{version}=dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/" \ + 'your_kit_profiler/logs,port=10002,sessionname=test-application-name') + end + end + + context do + let(:configuration) { super().merge 'default_session_name' => 'alternative-session-name' } + + it 'adds session name from configuration to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/your_kit_profiler/your_kit_profiler-' \ + "#{version}=dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/" \ + 'your_kit_profiler/logs,port=10001,sessionname=alternative-session-name') + end + end + + end + + end + +end From 2f7721de72fac07958d6357b29453f18a98a324f Mon Sep 17 00:00:00 2001 From: Nikhil Katre Date: Mon, 9 Nov 2015 14:35:49 -0800 Subject: [PATCH 095/812] AppDynamics default node name Previously the default node name for AppDynamics bound applications was the instance index. In certain views of AppDynamics, this wasn't a clear enough indicator of what was running. This change prepends the instance index with the application name. [#107769862][resolves #245] --- config/app_dynamics_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index ff4395b1bf..cf3fbba9de 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -18,5 +18,5 @@ version: 4.1.+ repository_root: ! '{default.repository.root}/app-dynamics' default_application_name: -default_node_name: ! '$(expr "$VCAP_APPLICATION" : ''.*instance_index[": ]*\([[:digit:]]*\).*'')' +default_node_name: ! '$(expr "$VCAP_APPLICATION" : ''.*application_name[": ]*\([-_a-zA-Z0-9]*\).*''):$(expr "$VCAP_APPLICATION" : ''.*instance_index[": ]*\([[:digit:]]*\).*'')' default_tier_name: From 1792eea25a317bc9147580eac940d173d15858df Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 9 Nov 2015 18:36:53 -0800 Subject: [PATCH 096/812] Additional diagnostics This change adds a debug diagnostic that prints the contents of an application. --- lib/java_buildpack/buildpack.rb | 7 +++++++ lib/java_buildpack/component/application.rb | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index c7099b77d1..007abc9ff1 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -104,6 +104,7 @@ def initialize(app_dir, application) @buildpack_version = BuildpackVersion.new log_environment_variables + log_application_contents mutable_java_home = Component::MutableJavaHome.new immutable_java_home = Component::ImmutableJavaHome.new mutable_java_home, app_dir @@ -168,6 +169,12 @@ def instantiate(components, java_home, component_info) end end + def log_application_contents + @logger.debug do + "Application Contents: #{Dir['**/*/', '**/*.*'].sort}" + end + end + def log_environment_variables @logger.debug { "Environment Variables: #{ENV.to_hash}" } end diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index efdd8e5db0..8a6a30dc72 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -39,7 +39,7 @@ class Application attr_reader :environment # @!attribute [r] root - # @return [JavaBuildpack::Util::FilteringPathname] the root of the application's fileystem filtered so that it + # @return [JavaBuildpack::Util::FilteringPathname] the root of the application's filesystem filtered so that it # only shows files that have been uploaded by the user attr_reader :root From c71590edc05d68a243cca1b3da8fe495f29bd841 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 9 Nov 2015 18:48:28 -0800 Subject: [PATCH 097/812] Better Diagnostics This change improves the application contents diagnostics. --- lib/java_buildpack/buildpack.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 007abc9ff1..e447560839 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -104,7 +104,7 @@ def initialize(app_dir, application) @buildpack_version = BuildpackVersion.new log_environment_variables - log_application_contents + log_application_contents application mutable_java_home = Component::MutableJavaHome.new immutable_java_home = Component::ImmutableJavaHome.new mutable_java_home, app_dir @@ -169,9 +169,12 @@ def instantiate(components, java_home, component_info) end end - def log_application_contents + def log_application_contents(application) @logger.debug do - "Application Contents: #{Dir['**/*/', '**/*.*'].sort}" + paths = [] + application.root.find { |f| paths << f.relative_path_from(application.root).to_s } + + "Application Contents: #{paths}" end end From cb5fe64d7b1562958749078154a9e4a5bcd56979 Mon Sep 17 00:00:00 2001 From: Violeta Georgieva Date: Wed, 11 Nov 2015 14:55:54 +0200 Subject: [PATCH 098/812] Fixed examples with Tomcat configuration env variable. Fixed some typos. --- docs/container-tomcat.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index 1d133fd76a..e572a2ed6b 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -53,13 +53,13 @@ The container can be configured by modifying the [`config/tomcat.yml`][] file in The version of Tomcat can be configured by setting an environment variable. ``` -$ cf set-env my-application JBP_CONFIG_TOMCAT 'tomcat: { version: 7.0.+ }' +$ cf set-env my-application JBP_CONFIG_TOMCAT '{tomcat: { version: 7.0.+ }}' ``` The context path that an application is deployed at can be configured by setting an environment variable. ``` -$ cf set-env my-application JBP_CONFIG_TOMCAT 'tomcat: { context_path: /first-segement/second-segment }' +$ cf set-env my-application JBP_CONFIG_TOMCAT '{tomcat: { context_path: /first-segment/second-segment }}' ``` @@ -67,7 +67,7 @@ $ cf set-env my-application JBP_CONFIG_TOMCAT 'tomcat: { context_path: /first-se The container can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/tomcat` directory in the buildpack fork. For example, to override the default `logging.properties` add your custom file to `resources/tomcat/conf/logging.properties`. ## Session Replication -By default, the Tomcat instance is configured to store all Sessions and their data in memory. Under certain cirmcumstances it my be appropriate to persist the Sessions and their data to a repository. When this is the case (small amounts of data that should survive the failure of any individual instance), the buildpack can automatically configure Tomcat to do so by binding an appropriate service. +By default, the Tomcat instance is configured to store all Sessions and their data in memory. Under certain circumstances it my be appropriate to persist the Sessions and their data to a repository. When this is the case (small amounts of data that should survive the failure of any individual instance), the buildpack can automatically configure Tomcat to do so by binding an appropriate service. ### Redis To enable Redis-based session replication, simply bind a Redis service containing a name, label, or tag that has `session-replication` as a substring. From c5eeb77f5b79c25b09141b2ecf211a8eb4cc84b3 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Tue, 17 Nov 2015 10:31:06 +0000 Subject: [PATCH 099/812] Update dependencies This commit updates the version ranges for MariaDB and GemFire. It also corrects a typo in the AppDynamics documentation. Fixes #251 --- config/maria_db_jdbc.yml | 2 +- config/tomcat.yml | 8 ++++---- docs/framework-app_dynamics_agent.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/maria_db_jdbc.yml b/config/maria_db_jdbc.yml index db68ffd72b..b1579b57ab 100644 --- a/config/maria_db_jdbc.yml +++ b/config/maria_db_jdbc.yml @@ -15,5 +15,5 @@ # Configuration for the MariaDB JDBC framework --- -version: 1.2.+ +version: 1.3.+ repository_root: ! '{default.repository.root}/mariadb-jdbc' diff --git a/config/tomcat.yml b/config/tomcat.yml index fcaebd3a57..5e6d87dec2 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -37,16 +37,16 @@ redis_store: connection_pool_size: 2 gemfire_store: gemfire: - version: 8.0.+ + version: 8.+ repository_root: ! '{default.repository.root}/gem-fire' gemfire_modules: - version: 8.0.+ + version: 8.+ repository_root: ! '{default.repository.root}/gem-fire-modules' gemfire_modules_tomcat7: - version: 8.0.+ + version: 8.+ repository_root: ! '{default.repository.root}/gem-fire-modules-tomcat7' gemfire_security: - version: 8.0.+ + version: 8.+ repository_root: ! '{default.repository.root}/gem-fire-security' gemfire_logging: version: 1.5.8 diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 337b0df05a..132018c81c 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -19,7 +19,7 @@ When binding AppDynamics using a user-provided service, it must have name or tag | ---- | ----------- | `account-access-key` | (Optional) The account access key to use when authenticating with the controller | `account-name` | (Optional) The account name to use when authenticating with the controller -| `application-name` | (Optional) the applicationa's name +| `application-name` | (Optional) the application's name | `host-name` | The controller host name | `node-name` | (Optional) the application's node name | `port` | (Optional) The controller port From fa8e68e97656858433482f546437004a38ad1562 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 17 Nov 2015 09:30:21 -0800 Subject: [PATCH 100/812] Enable Local Cache for Gemfire Since all requests are routed with sticky sessions, the Gemfire local cache should be enabled. This change makes that adjustment based on input from the Gemfire team. [#108245804][resolves #252] --- lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb | 2 +- spec/fixtures/container_tomcat_gemfire_store_context_after.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb b/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb index 49ca9596d2..7a5ee1ed9e 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb @@ -121,7 +121,7 @@ def add_manager(context) 'className' => PERSISTENT_MANAGER_CLASS, 'enableDebugListener' => 'false', 'enableGatewayReplication' => 'false', - 'enableLocalCache' => 'false', + 'enableLocalCache' => 'true', 'enableCommitValve' => 'true', 'preferDeserializedForm' => 'true', 'regionAttributesId' => 'PARTITION_REDUNDANT_PERSISTENT_OVERFLOW', diff --git a/spec/fixtures/container_tomcat_gemfire_store_context_after.xml b/spec/fixtures/container_tomcat_gemfire_store_context_after.xml index 09ee16687b..33f35c8425 100644 --- a/spec/fixtures/container_tomcat_gemfire_store_context_after.xml +++ b/spec/fixtures/container_tomcat_gemfire_store_context_after.xml @@ -15,5 +15,5 @@ ~ limitations under the License. --> - + From 5373a2b958427aed4f9286ae72ada28794a9b94a Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Wed, 18 Nov 2015 09:05:53 +0000 Subject: [PATCH 101/812] Update version range This commit updates the MariaDB Version range to be more accepting of new releases. --- config/maria_db_jdbc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/maria_db_jdbc.yml b/config/maria_db_jdbc.yml index b1579b57ab..dde360c415 100644 --- a/config/maria_db_jdbc.yml +++ b/config/maria_db_jdbc.yml @@ -15,5 +15,5 @@ # Configuration for the MariaDB JDBC framework --- -version: 1.3.+ +version: 1.+ repository_root: ! '{default.repository.root}/mariadb-jdbc' From ad5e668eaeb1b59dec94cfe6d7766c062d559d3e Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 18 Nov 2015 11:17:21 -0800 Subject: [PATCH 102/812] Luna HA Improvements This change updates the Luna HA support with improvements to the Chrystoki configuration file. --- lib/java_buildpack/framework/luna_security_provider.rb | 5 ++++- .../fixtures/framework_luna_security_provider/Chrystoki.conf | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 26f261442d..e70a543df4 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -151,6 +151,10 @@ def write_configuration(servers, groups) def write_epilogue(f) f.write < Date: Thu, 19 Nov 2015 09:09:54 +0200 Subject: [PATCH 103/812] Fixed test description. --- spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb index 2b0272ff38..ce3b579457 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb @@ -98,7 +98,7 @@ context do let(:configuration) { { 'context_path' => '/first-segment/second-segment' } } - it 'links only the application files and directories to the ROOT webapp', + it 'links only the application files and directories to the first-segment#second-segment webapp', app_fixture: 'container_tomcat_with_index', cache_fixture: 'stub-tomcat.tar.gz' do From 496724cee4b357f27300c851ffd38199fefa0b29 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 20 Nov 2015 11:59:43 -0800 Subject: [PATCH 104/812] Handle JAVA_OPTS the same way in Java Main as all other containers Previously, Java Main handled JAVA_OPTS differently than all other containers. Specifically, it added the opts directly to the command line rather than first placing them in an environment variable and then referencing that variable. This caused issues because you could not escape a variable the same way for all containers. This change causes a JAVA_OPTS environment variable to be written and then referenced later in the command. [#108647188][resolves #248] --- lib/java_buildpack/container/java_main.rb | 4 +- .../container/java_main_spec.rb | 55 +++++++++---------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index c2f3de5c23..d8fc96c02c 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -57,10 +57,12 @@ def release def release_text [ + @droplet.java_opts.as_env_var, + '&&', @droplet.environment_variables.as_env_vars, "#{qualify_path @droplet.java_home.root, @droplet.root}/bin/java", + '$JAVA_OPTS', @droplet.additional_libraries.as_classpath, - @droplet.java_opts.join(' '), main_class, arguments ].flatten.compact.join(' ') diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index 6ddf3309bf..ccaf7c3dd4 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -59,19 +59,21 @@ it 'returns command' do - expect(component.release).to eq("test-var-2 test-var-1 #{qualify_path java_home.root, droplet.root}/bin/java " \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ - ".additional_libs/test-jar-2.jar #{java_opts_str} test-java-main-class") + '.additional_libs/test-jar-2.jar test-java-main-class') end end it 'returns additional classpath entries when Class-Path is specified', app_fixture: 'container_main' do - expect(component.release).to eq("test-var-2 test-var-1 #{qualify_path java_home.root, droplet.root}/bin/java " \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ '.additional_libs/test-jar-2.jar:$PWD/alpha.jar:$PWD/bravo.jar:$PWD/' \ - "charlie.jar #{java_opts_str} test-main-class") + 'charlie.jar test-main-class') end context do @@ -79,37 +81,38 @@ it 'returns command line arguments when they are specified' do - expect(component.release).to eq("test-var-2 test-var-1 #{qualify_path java_home.root, droplet.root}/bin/java " \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ - "test-jar-2.jar #{java_opts_str} test-java-main-class some arguments") + 'test-jar-2.jar test-java-main-class some arguments') end end it 'releases Spring boot applications with a JarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_jar_launcher' do - expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - " #{java_opts_str} org.springframework.boot.loader.JarLauncher") + ' org.springframework.boot.loader.JarLauncher') end it 'releases Spring boot applications with a WarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_war_launcher' do - expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - " #{java_opts_str} org.springframework.boot.loader.WarLauncher") + ' org.springframework.boot.loader.WarLauncher') end it 'releases Spring boot applications with a PropertiesLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_properties_launcher' do - expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java -cp $PWD" \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - " #{java_opts_str} org.springframework.boot.loader.PropertiesLauncher") + ' org.springframework.boot.loader.PropertiesLauncher') end context do @@ -117,10 +120,10 @@ it 'releases Spring boot applications with a JarLauncher in the configuration by specifying a port' do - expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java -cp " \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp " \ '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ - "test-jar-2.jar #{java_opts_str} org.springframework.boot.loader.JarLauncher") + 'test-jar-2.jar org.springframework.boot.loader.JarLauncher') end end @@ -129,10 +132,10 @@ it 'releases Spring boot applications with a WarLauncher in the configuration by specifying a port' do - expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java -cp " \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp " \ '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ - "test-jar-2.jar #{java_opts_str} org.springframework.boot.loader.WarLauncher") + 'test-jar-2.jar org.springframework.boot.loader.WarLauncher') end end @@ -141,16 +144,12 @@ it 'releases Spring boot applications with a PropertiesLauncher in the configuration by specifying a port' do - expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java " \ + expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs' \ - "/test-jar-2.jar #{java_opts_str} org.springframework.boot.loader." \ + '/test-jar-2.jar org.springframework.boot.loader.' \ 'PropertiesLauncher') end end - def java_opts_str - java_opts.join(' ') - end - end From 4fdf10af279c342bc78d57607c514e38fadc33dd Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 23 Nov 2015 10:22:42 -0800 Subject: [PATCH 105/812] Java Main Eval This change adds an eval call to the Java Main container command. [#108647188][#248] --- lib/java_buildpack/container/java_main.rb | 1 + .../java_buildpack/container/java_main_spec.rb | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index d8fc96c02c..6ba6f0efee 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -60,6 +60,7 @@ def release_text @droplet.java_opts.as_env_var, '&&', @droplet.environment_variables.as_env_vars, + 'eval', "#{qualify_path @droplet.java_home.root, @droplet.root}/bin/java", '$JAVA_OPTS', @droplet.additional_libraries.as_classpath, diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index ccaf7c3dd4..f94b41da68 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -60,7 +60,7 @@ it 'returns command' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ '.additional_libs/test-jar-2.jar test-java-main-class') end @@ -70,7 +70,7 @@ app_fixture: 'container_main' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ '.additional_libs/test-jar-2.jar:$PWD/alpha.jar:$PWD/bravo.jar:$PWD/' \ 'charlie.jar test-main-class') @@ -82,7 +82,7 @@ it 'returns command line arguments when they are specified' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ 'test-jar-2.jar test-java-main-class some arguments') end @@ -92,7 +92,7 @@ app_fixture: 'container_main_spring_boot_jar_launcher' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ ' org.springframework.boot.loader.JarLauncher') end @@ -101,7 +101,7 @@ app_fixture: 'container_main_spring_boot_war_launcher' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ ' org.springframework.boot.loader.WarLauncher') end @@ -110,7 +110,7 @@ app_fixture: 'container_main_spring_boot_properties_launcher' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ ' org.springframework.boot.loader.PropertiesLauncher') end @@ -121,7 +121,7 @@ it 'releases Spring boot applications with a JarLauncher in the configuration by specifying a port' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp " \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp " \ '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ 'test-jar-2.jar org.springframework.boot.loader.JarLauncher') end @@ -133,7 +133,7 @@ it 'releases Spring boot applications with a WarLauncher in the configuration by specifying a port' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp " \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp " \ '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ 'test-jar-2.jar org.springframework.boot.loader.WarLauncher') end @@ -145,7 +145,7 @@ it 'releases Spring boot applications with a PropertiesLauncher in the configuration by specifying a port' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "#{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs' \ '/test-jar-2.jar org.springframework.boot.loader.' \ 'PropertiesLauncher') From df964cdbb70dabe4cceee80a30f03a4206ac01a1 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 23 Nov 2015 10:46:30 -0800 Subject: [PATCH 106/812] Exec commands A recent change to the execution commands had an unintended side- effect. By placing the memory calculator command in a separate process, connected via an &&, the process tree within a container changed. This change was mostly harmless except for the fact that only the root process (which was no longer the container process) is signaled for termination. This change updates all of the container release commands to prepend themselves with the bash command exec. This should cause the process tree to match its earlier behavior of making the container the root process. --- lib/java_buildpack/container/dist_zip_like.rb | 1 + lib/java_buildpack/container/groovy.rb | 1 + lib/java_buildpack/container/java_main.rb | 1 + .../container/spring_boot_cli.rb | 1 + lib/java_buildpack/container/tomcat.rb | 1 + lib/java_buildpack/util/play/base.rb | 1 + .../container/dist_zip_like_spec.rb | 2 +- spec/java_buildpack/container/groovy_spec.rb | 4 +-- .../container/java_main_spec.rb | 34 +++++++++---------- spec/java_buildpack/container/ratpack_spec.rb | 2 +- .../container/spring_boot_cli_spec.rb | 4 +-- .../container/spring_boot_spec.rb | 2 +- spec/java_buildpack/container/tomcat_spec.rb | 3 +- spec/java_buildpack/util/play/post22_spec.rb | 2 +- .../util/play/pre22_dist_spec.rb | 4 +-- .../util/play/pre22_staged_spec.rb | 2 +- 16 files changed, 36 insertions(+), 29 deletions(-) diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index afca3b5d69..a42d372e7b 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -44,6 +44,7 @@ def release @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, @droplet.java_opts.as_env_var, + 'exec', qualify_path(start_script(root), @droplet.root) ].flatten.compact.join(' ') end diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index 1991094087..7453c9102e 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -56,6 +56,7 @@ def release @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, @droplet.java_opts.as_env_var, + 'exec', qualify_path(@droplet.sandbox + 'bin/groovy', @droplet.root), @droplet.additional_libraries.as_classpath, relative_main_groovy, diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index 6ba6f0efee..8b815020bb 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -61,6 +61,7 @@ def release_text '&&', @droplet.environment_variables.as_env_vars, 'eval', + 'exec', "#{qualify_path @droplet.java_home.root, @droplet.root}/bin/java", '$JAVA_OPTS', @droplet.additional_libraries.as_classpath, diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index 568ea6847c..c9ea4355d4 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -51,6 +51,7 @@ def release @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, @droplet.java_opts.as_env_var, + 'exec', qualify_path(@droplet.sandbox + 'bin/spring', @droplet.root), 'run', @droplet.additional_libraries.as_classpath, diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 69033ba064..d4dec193a1 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -41,6 +41,7 @@ def command @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, @droplet.java_opts.as_env_var, + 'exec', "$PWD/#{(@droplet.sandbox + 'bin/catalina.sh').relative_path_from(@droplet.root)}", 'run' ].flatten.compact.join(' ') diff --git a/lib/java_buildpack/util/play/base.rb b/lib/java_buildpack/util/play/base.rb index 1bfe03c62f..96cc0e8dd5 100644 --- a/lib/java_buildpack/util/play/base.rb +++ b/lib/java_buildpack/util/play/base.rb @@ -56,6 +56,7 @@ def release [ @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, + 'exec', qualify_path(start_script, @droplet.root), java_opts ].flatten.compact.join(' ') diff --git a/spec/java_buildpack/container/dist_zip_like_spec.rb b/spec/java_buildpack/container/dist_zip_like_spec.rb index 3c1871fb8b..42ccfc96e0 100644 --- a/spec/java_buildpack/container/dist_zip_like_spec.rb +++ b/spec/java_buildpack/container/dist_zip_like_spec.rb @@ -52,7 +52,7 @@ app_fixture: 'container_dist_zip' do expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} " \ - 'JAVA_OPTS="test-opt-2 test-opt-1" $PWD/bin/application') + 'JAVA_OPTS="test-opt-2 test-opt-1" exec $PWD/bin/application') end end diff --git a/spec/java_buildpack/container/groovy_spec.rb b/spec/java_buildpack/container/groovy_spec.rb index 441d7d75ad..3c6e5d68f1 100644 --- a/spec/java_buildpack/container/groovy_spec.rb +++ b/spec/java_buildpack/container/groovy_spec.rb @@ -91,7 +91,7 @@ it 'returns command', app_fixture: 'container_groovy_main_method' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} " \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} exec " \ '$PWD/.java-buildpack/groovy/bin/groovy -cp $PWD/.additional_libs/test-jar-1.jar:' \ '$PWD/.additional_libs/test-jar-2.jar Application.groovy Alpha.groovy ' \ 'directory/Beta.groovy invalid.groovy') @@ -100,7 +100,7 @@ it 'returns command with included JARs', app_fixture: 'container_groovy_with_jars' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} " \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} exec " \ '$PWD/.java-buildpack/groovy/bin/groovy -cp $PWD/.additional_libs/test-jar-1.jar:' \ '$PWD/.additional_libs/test-jar-2.jar:$PWD/Alpha.jar:$PWD/directory/Beta.jar ' \ 'Application.groovy invalid.groovy') diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index f94b41da68..6a611cc485 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -60,7 +60,7 @@ it 'returns command' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ '.additional_libs/test-jar-2.jar test-java-main-class') end @@ -70,7 +70,7 @@ app_fixture: 'container_main' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ '.additional_libs/test-jar-2.jar:$PWD/alpha.jar:$PWD/bravo.jar:$PWD/' \ 'charlie.jar test-main-class') @@ -82,7 +82,7 @@ it 'returns command line arguments when they are specified' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ 'test-jar-2.jar test-java-main-class some arguments') end @@ -92,27 +92,27 @@ app_fixture: 'container_main_spring_boot_jar_launcher' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ - '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - ' org.springframework.boot.loader.JarLauncher') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + 'test-jar-2.jar org.springframework.boot.loader.JarLauncher') end it 'releases Spring boot applications with a WarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_war_launcher' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ - '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - ' org.springframework.boot.loader.WarLauncher') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + 'test-jar-2.jar org.springframework.boot.loader.WarLauncher') end it 'releases Spring boot applications with a PropertiesLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_properties_launcher' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp $PWD" \ - '/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar' \ - ' org.springframework.boot.loader.PropertiesLauncher') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + 'test-jar-2.jar org.springframework.boot.loader.PropertiesLauncher') end context do @@ -121,8 +121,8 @@ it 'releases Spring boot applications with a JarLauncher in the configuration by specifying a port' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp " \ - '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ 'test-jar-2.jar org.springframework.boot.loader.JarLauncher') end end @@ -133,8 +133,8 @@ it 'releases Spring boot applications with a WarLauncher in the configuration by specifying a port' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS -cp " \ - '$PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ 'test-jar-2.jar org.springframework.boot.loader.WarLauncher') end end @@ -145,7 +145,7 @@ it 'releases Spring boot applications with a PropertiesLauncher in the configuration by specifying a port' do expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs' \ '/test-jar-2.jar org.springframework.boot.loader.' \ 'PropertiesLauncher') diff --git a/spec/java_buildpack/container/ratpack_spec.rb b/spec/java_buildpack/container/ratpack_spec.rb index 3a955ad679..b1f945747e 100644 --- a/spec/java_buildpack/container/ratpack_spec.rb +++ b/spec/java_buildpack/container/ratpack_spec.rb @@ -70,7 +70,7 @@ app_fixture: 'container_ratpack_staged' do expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 " \ - 'test-opt-1" $PWD/bin/application') + 'test-opt-1" exec $PWD/bin/application') end end diff --git a/spec/java_buildpack/container/spring_boot_cli_spec.rb b/spec/java_buildpack/container/spring_boot_cli_spec.rb index 2cdac4a610..c9e2459f04 100644 --- a/spec/java_buildpack/container/spring_boot_cli_spec.rb +++ b/spec/java_buildpack/container/spring_boot_cli_spec.rb @@ -93,8 +93,8 @@ it 'returns command', app_fixture: 'container_spring_boot_cli_valid_app' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} " \ - "JAVA_OPTS=#{java_opts_str} $PWD/.java-buildpack/spring_boot_cli/bin/spring run " \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} " \ + 'exec $PWD/.java-buildpack/spring_boot_cli/bin/spring run ' \ '-cp $PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ 'directory/pogo_4.groovy invalid.groovy pogo_1.groovy pogo_2.groovy pogo_3.groovy') end diff --git a/spec/java_buildpack/container/spring_boot_spec.rb b/spec/java_buildpack/container/spring_boot_spec.rb index 8968fd640e..1e628908d4 100644 --- a/spec/java_buildpack/container/spring_boot_spec.rb +++ b/spec/java_buildpack/container/spring_boot_spec.rb @@ -70,7 +70,7 @@ app_fixture: 'container_spring_boot_staged' do expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} " \ - "JAVA_OPTS=#{java_opts_str} $PWD/bin/application") + "JAVA_OPTS=#{java_opts_str} exec $PWD/bin/application") end def env_vars_str diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index 04c13acb69..32276f77d3 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -84,7 +84,8 @@ it 'returns command' do expect(component.command).to eq("test-var-2 test-var-1 #{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 " \ - 'test-opt-1 -Dhttp.port=$PORT" $PWD/.java-buildpack/tomcat/bin/catalina.sh run') + 'test-opt-1 -Dhttp.port=$PORT" exec $PWD/.java-buildpack/tomcat/bin/catalina.sh' \ + ' run') end end diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index d22bd7a14c..b7f5f9433f 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -48,7 +48,7 @@ it 'returns command' do expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ - '$PWD/bin/play-application -Jtest-opt-2 -Jtest-opt-1 -J-Dhttp.port=$PORT') + 'exec $PWD/bin/play-application -Jtest-opt-2 -Jtest-opt-1 -J-Dhttp.port=$PORT') end context do diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index 6d09736779..43ff0f11c9 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -104,7 +104,7 @@ it 'returns command' do expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ - '$PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') + 'exec $PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') end end @@ -125,7 +125,7 @@ it 'returns command' do expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ - '$PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') + 'exec $PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') end end diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index 9f17dd6893..d6473a0dd6 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -104,7 +104,7 @@ it 'returns command' do expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ - '$PWD/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') + 'exec $PWD/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') end end From 1d461988f921f25a1d438ec1d9b6f5db3d063e87 Mon Sep 17 00:00:00 2001 From: Violeta Georgieva Date: Wed, 25 Nov 2015 10:24:36 +0200 Subject: [PATCH 107/812] Fixed comment when expanding Tomcat. --- lib/java_buildpack/container/tomcat/tomcat_instance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index 581af1bc88..d4caa7456e 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -87,7 +87,7 @@ def configure_linking end def expand(file) - with_timing "Expanding Tomcat to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do + with_timing "Expanding #{@component_name} to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do FileUtils.mkdir_p @droplet.sandbox shell "tar xzf #{file.path} -C #{@droplet.sandbox} --strip 1 --exclude webapps 2>&1" From 2b0f52b2ad7596f0dbdd51afa899361d848f3684 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 1 Dec 2015 15:59:29 -0800 Subject: [PATCH 108/812] Documentation polishing This change polishes up the debug documentation. --- docs/framework-debug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-debug.md b/docs/framework-debug.md index 522ae99347..1ab2af5fe0 100644 --- a/docs/framework-debug.md +++ b/docs/framework-debug.md @@ -33,7 +33,7 @@ $ cf ssh -N -T -L :localhost: The `REMOTE_PORT` should match the `port` configuration for the application (`8000` by default). The `LOCAL_PORT` can be any open port on your computer, but typically matches the `REMOTE_PORT` where possible. -Once the SSH tunnel has been created, your IDE should connect to `localhost` for debugging. +Once the SSH tunnel has been created, your IDE should connect to `localhost:8000` for debugging. ![Eclipse Configuration](framework-debug-eclipse.png) From 4f1ca7da2518139804fef8960f50785039217522 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 1 Dec 2015 16:00:01 -0800 Subject: [PATCH 109/812] Documentation polishing This change polishes up the JMX documentation. --- docs/framework-jmx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-jmx.md b/docs/framework-jmx.md index 7ef118bb42..5669e33119 100644 --- a/docs/framework-jmx.md +++ b/docs/framework-jmx.md @@ -32,7 +32,7 @@ $ cf ssh -N -T -L :localhost: The `REMOTE_PORT` should match the `port` configuration for the application (`5000` by default). The `LOCAL_PORT` can be any open port on your computer, but typically matches the `REMOTE_PORT` where possible. -Once the SSH tunnel has been created, your JConsole should connect to `localhost:` for debugging. +Once the SSH tunnel has been created, your JConsole should connect to `localhost:` for JMX access. ![JConsole Configuration](framework-jmx-jconsole.png) From f497475dee015b0a79e9812c44b74a523b32a436 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 1 Dec 2015 16:00:46 -0800 Subject: [PATCH 110/812] Documentation polishing This change polishes the Debug documentation. --- docs/framework-debug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-debug.md b/docs/framework-debug.md index 1ab2af5fe0..754ffb7e93 100644 --- a/docs/framework-debug.md +++ b/docs/framework-debug.md @@ -33,7 +33,7 @@ $ cf ssh -N -T -L :localhost: The `REMOTE_PORT` should match the `port` configuration for the application (`8000` by default). The `LOCAL_PORT` can be any open port on your computer, but typically matches the `REMOTE_PORT` where possible. -Once the SSH tunnel has been created, your IDE should connect to `localhost:8000` for debugging. +Once the SSH tunnel has been created, your IDE should connect to `localhost:` for debugging. ![Eclipse Configuration](framework-debug-eclipse.png) From 4985ea7dd8a7e6b1f759cf49d885a59edbb4de52 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 2 Dec 2015 09:55:33 -0800 Subject: [PATCH 111/812] Remove the user of expr Previously, there were a number of places where we used $(expr ...) to parse the contents the VCAP_APPLICATION environment variable at runtime. Unbeknownst to us expr has a special case where, if the returned value of the expression is 0, it exits. As we were using expr to parse the instance_index, applications would start all of their instances, except the 0th instance. As you can imagine, this took quite some time to detect. This change dumps the use of $(expr ..) in favor of $(ruby -e ...). While this now ties us to ruby being available in the environment, it does give us some serious advantages. First off, we can parse out the 0th instance_index. Secondly we can now write much more understandable expressions like "#{a['application_name']}:#{a['instance_index']}". [1]: http://unix.stackexchange.com/questions/63166/bash-e-exits-when-let-or-expr-evaluates-to-0 --- config/app_dynamics_agent.yml | 2 +- config/introscope_agent.yml | 2 +- config/your_kit_profiler.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index cf3fbba9de..a7757cf3ce 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -18,5 +18,5 @@ version: 4.1.+ repository_root: ! '{default.repository.root}/app-dynamics' default_application_name: -default_node_name: ! '$(expr "$VCAP_APPLICATION" : ''.*application_name[": ]*\([-_a-zA-Z0-9]*\).*''):$(expr "$VCAP_APPLICATION" : ''.*instance_index[": ]*\([[:digit:]]*\).*'')' +default_node_name: ! '$(ruby -e "require ''json'' ; a = JSON.parse(ENV[''VCAP_APPLICATION'']); puts \"#{a[''application_name'']}:#{a[''instance_index'']}\"")' default_tier_name: diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index a3e61596fc..f38fc48388 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -17,4 +17,4 @@ --- repository_root: "" version: 9.7.+ -default_agent_name: "$(expr \"$VCAP_APPLICATION\" : \'.*application_name[\": ]*\\([A-Za-z0-9_-]*\\).*\')" +default_agent_name: ! '$(ruby -e "require ''json'' ; puts JSON.parse(ENV[''VCAP_APPLICATION''])[''application_name'']")' diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml index d7a9085f8f..59211543e5 100644 --- a/config/your_kit_profiler.yml +++ b/config/your_kit_profiler.yml @@ -19,4 +19,4 @@ version: 2015.+ repository_root: ! '{default.repository.root}/your-kit/{platform}/{architecture}' enabled: false port: 10001 -default_session_name: ! '$(expr "$VCAP_APPLICATION" : ''.*application_name[": ]*\([-_a-zA-Z0-9]*\).*''):$(expr "$VCAP_APPLICATION" : ''.*instance_index[": ]*\([[:digit:]]*\).*'')' +default_session_name: ! '$(ruby -e "require ''json'' ; a = JSON.parse(ENV[''VCAP_APPLICATION'']); puts \"#{a[''application_name'']}:#{a[''instance_index'']}\"")' From 7ef31df55264b9919d46bd2e4d07623473268e38 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 4 Dec 2015 10:32:59 -0800 Subject: [PATCH 112/812] Secure JRebel Previously the JRebel dependency was downloaded via an http:// URI opening the possibility of a Man-in-the-Middle attack. This change updates the repository_root URI to use https:// instead, preventing that attack. [#109442964][resolves #262] --- config/jrebel_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml index 7636f4954a..71a1f74537 100644 --- a/config/jrebel_agent.yml +++ b/config/jrebel_agent.yml @@ -16,4 +16,4 @@ # Configuration for the JRebel framework --- version: 6.+ -repository_root: http://dl.zeroturnaround.com/jrebel +repository_root: https://dl.zeroturnaround.com/jrebel From d0133bde1b1e18578a97d6a1fa2b45368a0fd105 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Dec 2015 10:36:43 -0800 Subject: [PATCH 113/812] JMX Port Documentation Previously the documentation for the JMX framework stated that the LOCAL_PORT and REMOTE_PORT could be different from one another. Due to limitations from JMX using RMI this isn't true. This change updates the documentation to state that the port numbers must match. [#109651014][resolves #266] --- docs/framework-jmx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-jmx.md b/docs/framework-jmx.md index 5669e33119..64fd147e7e 100644 --- a/docs/framework-jmx.md +++ b/docs/framework-jmx.md @@ -30,7 +30,7 @@ After starting an application with JMX enabled, an SSH tunnel must be created to $ cf ssh -N -T -L :localhost: ``` -The `REMOTE_PORT` should match the `port` configuration for the application (`5000` by default). The `LOCAL_PORT` can be any open port on your computer, but typically matches the `REMOTE_PORT` where possible. +The `REMOTE_PORT` should match the `port` configuration for the application (`5000` by default). The `LOCAL_PORT` must matche the `REMOTE_PORT`. Once the SSH tunnel has been created, your JConsole should connect to `localhost:` for JMX access. From 380a179d1ffd78ae5905b45f8b5a57bd15212dc9 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Dec 2015 13:49:44 -0800 Subject: [PATCH 114/812] Loosen Luna Version This change loosens the Luna client version from 5.3.+ to 5.+. --- config/luna_security_provider.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index 4c6b4f4aa1..b0cc80cd1f 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -15,5 +15,5 @@ # Configuration for the Dynatrace framework --- -version: 5.3.+ +version: 5.+ repository_root: "" From 0d59087a728a7983663dadb08cc1c678ed0d5fa1 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Dec 2015 16:06:30 -0800 Subject: [PATCH 115/812] Luna Security Provider Logging This change updates the Luna Security Provider framework to allow users to enable the cklog wrapper for the Luna libraries. Logging is disabled by default and required Luna client 5.4.2 Alpha 2 or later. --- .idea/dictionaries/bhale.xml | 5 ++ config/luna_security_provider.yml | 1 + docs/framework-luna_security_provider.md | 1 + .../framework/luna_security_provider.rb | 45 +++++++++++++ .../luna_security_provider/Chrystoki.conf | 5 -- .../Chrystoki.conf | 9 ++- .../Chrystoki.conf | 62 ++++++++++++++++++ .../client-certificate.pem | 3 + .../client-private-key.pem | 3 + .../server-certificates.pem | 6 ++ spec/fixtures/stub-luna-security-provider.tar | Bin 51200 -> 62976 bytes .../framework/luna_security_provider_spec.rb | 27 +++++++- 12 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf create mode 100644 spec/fixtures/framework_luna_security_provider_logging/client-certificate.pem create mode 100644 spec/fixtures/framework_luna_security_provider_logging/client-private-key.pem create mode 100644 spec/fixtures/framework_luna_security_provider_logging/server-certificates.pem diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 3df374525b..a73f3cf436 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -6,11 +6,13 @@ argv atpack chrystoki + cklog codeclimate constantized constantizes cpio creat + cryptoki dhttp dirname distapplication @@ -37,10 +39,13 @@ jsome jtest killjava + libcklog + libcrpytoki libcryptoki libyjpagent ljust lunaclient + lunajsp mainclass metaspace mkdir diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index b0cc80cd1f..55f4ac2321 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -17,3 +17,4 @@ --- version: 5.+ repository_root: "" +logging_enabled: false diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md index ab4106cb2a..13f356171d 100644 --- a/docs/framework-luna_security_provider.md +++ b/docs/framework-luna_security_provider.md @@ -91,6 +91,7 @@ The framework can be configured by modifying the [`config/luna_security_provider | Name | Description | ---- | ----------- +| `logging_enabled` | Whether to enable the logging wrapper for the Luna Security Provider. Defaults to `false`. | `repository_root` | The URL of the Luna Security Provider repository index ([details][repositories]). | `version` | Version of the Luna Security Provider to use. diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index e70a543df4..cff4b327a8 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -63,6 +63,10 @@ def chrystoki @droplet.sandbox + 'Chrystoki.conf' end + def cklog(root) + Dir[root + 'cklog-*.x86_64.rpm'][0] + end + def client_certificate @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem' end @@ -95,6 +99,10 @@ def install_client(root) Dir.chdir(@droplet.sandbox) do shell "#{rpm2cpio} < #{libcrpytoki root} | cpio -id ./usr/safenet/lunaclient/lib/libCryptoki2_64.so" shell "#{rpm2cpio} < #{lunajsp root} | cpio -id ./usr/safenet/lunaclient/jsp/lib/*" + + if logging? + shell "#{rpm2cpio} < #{cklog root} | cpio -id ./usr/safenet/lunaclient/lib/libcklog2.so" + end end end @@ -102,6 +110,10 @@ def libcrpytoki(root) Dir[root + 'libcryptoki-*.x86_64.rpm'][0] end + def logging? + @configuration['logging_enabled'] + end + def lunajsp(root) Dir[root + 'lunajsp-*.x86_64.rpm'][0] end @@ -167,7 +179,40 @@ def write_group(f, index, group) f.write "\n" end + def write_lib(f) + f.write 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 K)WE3H!2bj7fmwtA delta 4153 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 G{Qm+)T~GS} diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index 6b3e36673d..d20c50267e 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -72,13 +72,14 @@ expect(sandbox + 'java.security').to exist end - it 'unpacks the luna jar', + it 'unpacks the luna tar', cache_fixture: 'stub-luna-security-provider.tar' do component.compile expect(sandbox + 'usr/safenet/lunaclient/lib/libCryptoki2_64.so').to exist expect(sandbox + 'usr/safenet/lunaclient/jsp/lib/stub.file').to exist + expect(sandbox + 'usr/safenet/lunaclient/lib/libcklog2.so').not_to exist end it 'write certificate files', @@ -120,6 +121,30 @@ 'luna_security_provider/usr/safenet/lunaclient/jsp/lib') end + context do + let(:configuration) { { 'logging_enabled' => true } } + + it 'unpacks the luna tar', + cache_fixture: 'stub-luna-security-provider.tar' do + + component.compile + + expect(sandbox + 'usr/safenet/lunaclient/lib/libCryptoki2_64.so').to exist + expect(sandbox + 'usr/safenet/lunaclient/jsp/lib/stub.file').to exist + expect(sandbox + 'usr/safenet/lunaclient/lib/libcklog2.so').to exist + end + + it 'writes configuration', + cache_fixture: 'stub-luna-security-provider.tar' do + + component.compile + + expect(sandbox + 'Chrystoki.conf').to exist + check_file_contents(sandbox + 'Chrystoki.conf', + 'spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf') + end + end + def check_file_contents(actual, expected) expect(File.read(actual)).to eq File.read(expected) end From 8c2dec5455da459cf59bec963183c6409cd6c976 Mon Sep 17 00:00:00 2001 From: Violeta Georgieva Date: Tue, 8 Dec 2015 17:25:53 +0200 Subject: [PATCH 116/812] Fixed servlet example - the buildpack location was provided twice. --- docs/example-servlet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/example-servlet.md b/docs/example-servlet.md index d7a212dfd3..4a4932040b 100644 --- a/docs/example-servlet.md +++ b/docs/example-servlet.md @@ -26,7 +26,7 @@ The following example shows how deploy the sample application located in the [Ja ```bash $ mvn package -$ cf push web-servlet-2-application -p target/web-servlet-2-application-1.0.0.BUILD-SNAPSHOT.war -b https://github.com/cloudfoundry/java-buildpack.git -b https://github.com/cloudfoundry/java-buildpack.git +$ cf push web-servlet-2-application -p target/web-servlet-2-application-1.0.0.BUILD-SNAPSHOT.war -b https://github.com/cloudfoundry/java-buildpack.git -----> Downloading Open Jdk JRE 1.7.0_51 from http://.../openjdk/lucid/x86_64/openjdk-1.7.0_51.tar.gz (0.0s) Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.1s) From 76e59743a87d7f6e748ba100a56dabd0bf336de7 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 8 Jan 2016 13:38:17 -0800 Subject: [PATCH 117/812] Polishing Cleaning up ordering and format. --- lib/java_buildpack/buildpack.rb | 2 +- lib/java_buildpack/component/application.rb | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index e447560839..4efe10f7a2 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -219,8 +219,8 @@ class << self # @return [Object] the return value from the given block def with_buildpack(app_dir, message) app_dir = Pathname.new(File.expand_path(app_dir)) - application = Component::Application.new(app_dir) Logging::LoggerFactory.instance.setup app_dir + application = Component::Application.new(app_dir) yield new(app_dir, application) if block_given? rescue => e diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index 8a6a30dc72..82653957ae 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -51,8 +51,9 @@ class Application # # @param [Pathname] root the root of the application def initialize(root) - initial = children(root) - @root = JavaBuildpack::Util::FilteringPathname.new(root, ->(path) { initial.member? path }, false) + log_file = JavaBuildpack::Logging::LoggerFactory.instance.log_file + initial = children(root).delete(log_file) + @root = JavaBuildpack::Util::FilteringPathname.new(root, ->(path) { initial.member? path }, false) @environment = ENV.to_hash @details = parse(@environment.delete('VCAP_APPLICATION')) From bc413433f93841a1781bacb7b3fa372ad3e9dcaa Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 8 Jan 2016 14:04:59 -0800 Subject: [PATCH 118/812] Test Failure Fixes This change updates some of the test code to fix build breakages from the previous commit. --- spec/application_helper.rb | 2 ++ .../util/filtering_pathname_spec.rb | 16 ++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/spec/application_helper.rb b/spec/application_helper.rb index 6d1ec93e9c..f40d59a5d2 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -17,6 +17,7 @@ require 'spec_helper' require 'java_buildpack/component/application' require 'java_buildpack/component/services' +require 'java_buildpack/logging/logger_factory' require 'json' shared_context 'application_helper' do @@ -39,6 +40,7 @@ end let(:application) do + JavaBuildpack::Logging::LoggerFactory.instance.setup app_dir JavaBuildpack::Component::Application.new app_dir end diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index 4b8e4b4750..f9c73334d4 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -169,7 +169,8 @@ filtering_target.each_entry do |entry| entries << entry end - expect(entries.to_set).to eq([Pathname.new('.'), Pathname.new('..'), Pathname.new('good')].to_set) + expect(entries.to_set) + .to eq([Pathname.new('.'), Pathname.new('..'), Pathname.new('.java-buildpack.log'), Pathname.new('good')].to_set) end it 'delegates each_line when the file is filtered in' do @@ -184,7 +185,8 @@ end it 'returns each visible entry from entries' do - expect(filtering_target.entries.to_set).to eq([Pathname.new('.'), Pathname.new('..'), Pathname.new('good')].to_set) + expect(filtering_target.entries.to_set) + .to eq([Pathname.new('.'), Pathname.new('..'), Pathname.new('.java-buildpack.log'), Pathname.new('good')].to_set) end it 'delegates opendir when the directory is filtered in' do @@ -208,19 +210,21 @@ end it 'returns each child as a filtered pathname from children' do - expect(filtering_target.children).to eq([app_dir + 'good']) + expect(filtering_target.children).to eq([app_dir + '.java-buildpack.log', app_dir + 'good']) end it 'returns each child as a pathname from children(false)' do - expect(filtering_target.children(false)).to eq([Pathname.new('good')]) + expect(filtering_target.children(false)).to eq([Pathname.new('.java-buildpack.log'), Pathname.new('good')]) end it 'yields each child as a filtered pathname from each_child' do - expect { |b| filtering_target.each_child(&b) }.to yield_successive_args(app_dir + 'good') + expect { |b| filtering_target.each_child(&b) } + .to yield_successive_args(app_dir + '.java-buildpack.log', app_dir + 'good') end it 'yields each child as a pathname from each_child(false)' do - expect { |b| filtering_target.each_child(false, &b) }.to yield_successive_args(Pathname.new('good')) + expect { |b| filtering_target.each_child(false, &b) } + .to yield_successive_args(Pathname.new('.java-buildpack.log'), Pathname.new('good')) end it 'yields each component of the path from each_filename' do From 405ee341fdedcd1b9afbcb187c64c8dc370fa131 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 8 Jan 2016 14:31:47 -0800 Subject: [PATCH 119/812] Revert "Test Failure Fixes" This reverts commit bc413433f93841a1781bacb7b3fa372ad3e9dcaa. --- spec/application_helper.rb | 2 -- .../util/filtering_pathname_spec.rb | 16 ++++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/spec/application_helper.rb b/spec/application_helper.rb index f40d59a5d2..6d1ec93e9c 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -17,7 +17,6 @@ require 'spec_helper' require 'java_buildpack/component/application' require 'java_buildpack/component/services' -require 'java_buildpack/logging/logger_factory' require 'json' shared_context 'application_helper' do @@ -40,7 +39,6 @@ end let(:application) do - JavaBuildpack::Logging::LoggerFactory.instance.setup app_dir JavaBuildpack::Component::Application.new app_dir end diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index f9c73334d4..4b8e4b4750 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -169,8 +169,7 @@ filtering_target.each_entry do |entry| entries << entry end - expect(entries.to_set) - .to eq([Pathname.new('.'), Pathname.new('..'), Pathname.new('.java-buildpack.log'), Pathname.new('good')].to_set) + expect(entries.to_set).to eq([Pathname.new('.'), Pathname.new('..'), Pathname.new('good')].to_set) end it 'delegates each_line when the file is filtered in' do @@ -185,8 +184,7 @@ end it 'returns each visible entry from entries' do - expect(filtering_target.entries.to_set) - .to eq([Pathname.new('.'), Pathname.new('..'), Pathname.new('.java-buildpack.log'), Pathname.new('good')].to_set) + expect(filtering_target.entries.to_set).to eq([Pathname.new('.'), Pathname.new('..'), Pathname.new('good')].to_set) end it 'delegates opendir when the directory is filtered in' do @@ -210,21 +208,19 @@ end it 'returns each child as a filtered pathname from children' do - expect(filtering_target.children).to eq([app_dir + '.java-buildpack.log', app_dir + 'good']) + expect(filtering_target.children).to eq([app_dir + 'good']) end it 'returns each child as a pathname from children(false)' do - expect(filtering_target.children(false)).to eq([Pathname.new('.java-buildpack.log'), Pathname.new('good')]) + expect(filtering_target.children(false)).to eq([Pathname.new('good')]) end it 'yields each child as a filtered pathname from each_child' do - expect { |b| filtering_target.each_child(&b) } - .to yield_successive_args(app_dir + '.java-buildpack.log', app_dir + 'good') + expect { |b| filtering_target.each_child(&b) }.to yield_successive_args(app_dir + 'good') end it 'yields each child as a pathname from each_child(false)' do - expect { |b| filtering_target.each_child(false, &b) } - .to yield_successive_args(Pathname.new('.java-buildpack.log'), Pathname.new('good')) + expect { |b| filtering_target.each_child(false, &b) }.to yield_successive_args(Pathname.new('good')) end it 'yields each component of the path from each_filename' do From 834926b4cc394966b66a4813b44da7724adec37f Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 8 Jan 2016 14:34:19 -0800 Subject: [PATCH 120/812] Test fixes Another attempt at fixing broken test from previous commit --- lib/java_buildpack/component/application.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index 82653957ae..d5598a7a7f 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -51,9 +51,14 @@ class Application # # @param [Pathname] root the root of the application def initialize(root) - log_file = JavaBuildpack::Logging::LoggerFactory.instance.log_file - initial = children(root).delete(log_file) - @root = JavaBuildpack::Util::FilteringPathname.new(root, ->(path) { initial.member? path }, false) + initial = children(root) + + if Logging::LoggerFactory.instance.initialized + log_file = JavaBuildpack::Logging::LoggerFactory.instance.log_file + initial.delete(log_file) + end + + @root = JavaBuildpack::Util::FilteringPathname.new(root, ->(path) { initial.member? path }, false) @environment = ENV.to_hash @details = parse(@environment.delete('VCAP_APPLICATION')) From e2e0c53f0f5af807e414c6af7dd9907388f2a858 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 8 Jan 2016 17:15:35 -0800 Subject: [PATCH 121/812] Enable Log File Previously, the Java Buildpack logfile was written to the file system under all circumstances. This change updates the LoggerFactory to only create the file if it explicitly configured to do so. --- config/logging.yml | 3 ++- lib/java_buildpack/logging/logger_factory.rb | 18 +++++++++++------- .../logging/logger_factory_spec.rb | 2 +- .../util/cache/internet_availability_spec.rb | 8 ++++++-- spec/logging_helper.rb | 12 +++++++++--- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/config/logging.yml b/config/logging.yml index bdd017df62..245b885919 100644 --- a/config/logging.yml +++ b/config/logging.yml @@ -15,4 +15,5 @@ # Logging configuration --- -default_log_level: INFO \ No newline at end of file +default_log_level: INFO +enable_log_file: false diff --git a/lib/java_buildpack/logging/logger_factory.rb b/lib/java_buildpack/logging/logger_factory.rb index 37984fde14..c2d51f1108 100644 --- a/lib/java_buildpack/logging/logger_factory.rb +++ b/lib/java_buildpack/logging/logger_factory.rb @@ -46,8 +46,13 @@ def initialize # @return [Void] def setup(app_dir) @monitor.synchronize do - @log_file = app_dir + '.java-buildpack.log' - @delegates = [file_logger, console_logger] + configuration = JavaBuildpack::Util::ConfigurationUtils.load('logging', true, false) + + @log_file = app_dir + '.java-buildpack.log' + + @delegates = [console_logger(configuration)] + @delegates << file_logger if configuration['enable_log_file'] + @initialized = true end end @@ -100,9 +105,9 @@ def get_logger(klass) private - def console_logger + def console_logger(configuration) logger = Logger.new($stderr) - logger.level = severity + logger.level = severity(configuration) logger.formatter = lambda do |severity, _datetime, klass, message| "#{klass.ljust(32)} #{severity.ljust(5)} #{message}\n" end @@ -126,11 +131,10 @@ def ruby_mode $VERBOSE || $DEBUG ? 'DEBUG' : nil end - def severity + def severity(configuration) severity = ENV['JBP_LOG_LEVEL'] severity = ruby_mode unless severity - severity = - JavaBuildpack::Util::ConfigurationUtils.load('logging', true, false)['default_log_level'] unless severity + severity = configuration['default_log_level'] unless severity severity = 'INFO' unless severity "::Logger::Severity::#{severity.upcase}".constantize diff --git a/spec/java_buildpack/logging/logger_factory_spec.rb b/spec/java_buildpack/logging/logger_factory_spec.rb index 92056a88bd..7043ed1f2e 100644 --- a/spec/java_buildpack/logging/logger_factory_spec.rb +++ b/spec/java_buildpack/logging/logger_factory_spec.rb @@ -31,7 +31,7 @@ end it 'logs all levels to file', - log_level: 'FATAL' do + :enable_log_file, log_level: 'FATAL' do trigger diff --git a/spec/java_buildpack/util/cache/internet_availability_spec.rb b/spec/java_buildpack/util/cache/internet_availability_spec.rb index 99e6f1916d..9b73d08e80 100644 --- a/spec/java_buildpack/util/cache/internet_availability_spec.rb +++ b/spec/java_buildpack/util/cache/internet_availability_spec.rb @@ -41,14 +41,18 @@ end end - it 'records availability' do + it 'records availability', + :enable_log_file do + described_class.instance.available false expect(described_class.instance.available?).not_to be expect(log_contents).not_to match(/Internet availability set to false/) end - it 'records availability with message' do + it 'records availability with message', + :enable_log_file do + described_class.instance.available false, 'test message' expect(described_class.instance.available?).not_to be diff --git a/spec/logging_helper.rb b/spec/logging_helper.rb index 308701972b..4c03714a2d 100644 --- a/spec/logging_helper.rb +++ b/spec/logging_helper.rb @@ -19,11 +19,13 @@ require 'console_helper' require 'fileutils' require 'java_buildpack/logging/logger_factory' +require 'yaml' shared_context 'logging_helper' do include_context 'console_helper' include_context 'application_helper' + previous_log_config = ENV['JBP_CONFIG_LOGGING'] previous_log_level = ENV['JBP_LOG_LEVEL'] previous_debug_level = $DEBUG previous_verbose_level = $VERBOSE @@ -34,6 +36,9 @@ log_level = example.metadata[:log_level] ENV['JBP_LOG_LEVEL'] = log_level if log_level + enable_log_file = example.metadata[:enable_log_file] + ENV['JBP_CONFIG_LOGGING'] = { 'enable_log_file' => true }.to_yaml if enable_log_file + $DEBUG = example.metadata[:debug] $VERBOSE = example.metadata[:verbose] @@ -43,9 +48,10 @@ after do JavaBuildpack::Logging::LoggerFactory.instance.reset - ENV['JBP_LOG_LEVEL'] = previous_log_level - $VERBOSE = previous_verbose_level - $DEBUG = previous_debug_level + ENV['JBP_CONFIG_LOGGING'] = previous_log_config + ENV['JBP_LOG_LEVEL'] = previous_log_level + $VERBOSE = previous_verbose_level + $DEBUG = previous_debug_level end end From 3c26699d7dda68d34d9b00fa9adb472493ea4db6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 21 Jan 2016 16:43:45 -0800 Subject: [PATCH 122/812] Additional Luna HA Configuration Previously the Luna Security Provider configuration specified HA requirements, but did not describe the reconnection configuration. This change adds additional parameters that describe the reconnection behavior. [#101905646] --- lib/java_buildpack/framework/luna_security_provider.rb | 2 ++ spec/fixtures/framework_luna_security_provider/Chrystoki.conf | 2 ++ .../framework_luna_security_provider_logging/Chrystoki.conf | 2 ++ 3 files changed, 6 insertions(+) diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index cff4b327a8..c59127871e 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -165,7 +165,9 @@ def write_epilogue(f) } HAConfiguration = { + AutoReconnectInterval = 60; HAOnly = 1; + ReconnAtt = 20; } EOS end diff --git a/spec/fixtures/framework_luna_security_provider/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider/Chrystoki.conf index c7111534e7..cdb2ac905c 100644 --- a/spec/fixtures/framework_luna_security_provider/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider/Chrystoki.conf @@ -50,5 +50,7 @@ VirtualToken = { } HAConfiguration = { + AutoReconnectInterval = 60; HAOnly = 1; + ReconnAtt = 20; } diff --git a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf index 59a9568caf..9d4c34d1f9 100644 --- a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf @@ -58,5 +58,7 @@ VirtualToken = { } HAConfiguration = { + AutoReconnectInterval = 60; HAOnly = 1; + ReconnAtt = 20; } From 5ceccb103a41c20644a64d74cae8c8f4332598c9 Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Thu, 28 Jan 2016 18:35:40 +0000 Subject: [PATCH 123/812] Add missing GemFire dependencies This commit adds missing GemFire dependencies on Log4j. --- .rubocop.yml | 2 +- config/tomcat.yml | 19 ++++++- .../tomcat/gemfire/gemfire_log4j_api.rb | 53 ++++++++++++++++++ .../tomcat/gemfire/gemfire_log4j_core.rb | 53 ++++++++++++++++++ .../tomcat/gemfire/gemfire_log4j_jcl.rb | 53 ++++++++++++++++++ .../tomcat/gemfire/gemfire_log4j_jul.rb | 53 ++++++++++++++++++ .../gemfire/gemfire_log4j_slf4j_impl.rb | 53 ++++++++++++++++++ .../container/tomcat/tomcat_gemfire_store.rb | 10 ++++ spec/fixtures/stub-gemfire-log4j-api.jar | Bin 0 -> 2658 bytes spec/fixtures/stub-gemfire-log4j-core.jar | Bin 0 -> 2658 bytes spec/fixtures/stub-gemfire-log4j-jcl.jar | Bin 0 -> 2658 bytes spec/fixtures/stub-gemfire-log4j-jul.jar | Bin 0 -> 2658 bytes .../stub-gemfire-log4j-slf4j-impl.jar | Bin 0 -> 2658 bytes .../tomcat/gemfire/gemfire_log4j_api_spec.rb | 42 ++++++++++++++ .../tomcat/gemfire/gemfire_log4j_core_spec.rb | 42 ++++++++++++++ .../tomcat/gemfire/gemfire_log4j_jcl_spec.rb | 42 ++++++++++++++ .../tomcat/gemfire/gemfire_log4j_jul_spec.rb | 42 ++++++++++++++ .../gemfire/gemfire_log4j_slf4j_impl_spec.rb | 42 ++++++++++++++ 18 files changed, 503 insertions(+), 3 deletions(-) create mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb create mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb create mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb create mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb create mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb create mode 100644 spec/fixtures/stub-gemfire-log4j-api.jar create mode 100644 spec/fixtures/stub-gemfire-log4j-core.jar create mode 100644 spec/fixtures/stub-gemfire-log4j-jcl.jar create mode 100644 spec/fixtures/stub-gemfire-log4j-jul.jar create mode 100644 spec/fixtures/stub-gemfire-log4j-slf4j-impl.jar create mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api_spec.rb create mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core_spec.rb create mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl_spec.rb create mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul_spec.rb create mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index 89ed16fc24..48a6803521 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,7 +9,7 @@ AllCops: - 'build/**/*' - 'vendor/**/*' Metrics/AbcSize: - Max: 18 + Max: 22 Metrics/ClassLength: Max: 200 Metrics/CyclomaticComplexity: diff --git a/config/tomcat.yml b/config/tomcat.yml index 5e6d87dec2..4623da2289 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -49,8 +49,23 @@ gemfire_store: version: 8.+ repository_root: ! '{default.repository.root}/gem-fire-security' gemfire_logging: - version: 1.5.8 + version: 1.7.7 repository_root: ! '{default.repository.root}/slf4j-jdk14' gemfire_logging_api: - version: 1.5.8 + version: 1.7.7 repository_root: ! '{default.repository.root}/slf4j-api' + gemfire_log4j_api: + version: 2.1.0 + repository_root: ! '{default.repository.root}/log4j-api' + gemfire_log4j_core: + version: 2.1.0 + repository_root: ! '{default.repository.root}/log4j-core' + gemfire_log4j_jcl: + version: 2.1.0 + repository_root: ! '{default.repository.root}/log4j-jcl' + gemfire_log4j_jul: + version: 2.1.0 + repository_root: ! '{default.repository.root}/log4j-jul' + gemfire_log4j_slf4j_impl: + version: 2.1.0 + repository_root: ! '{default.repository.root}/log4j-slf4j-impl' diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb new file mode 100644 index 0000000000..666e7f08e2 --- /dev/null +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb @@ -0,0 +1,53 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/container' +require 'java_buildpack/container/tomcat/tomcat_utils' +require 'java_buildpack/logging/logger_factory' + +module JavaBuildpack + module Container + + # Encapsulates the detect, compile, and release functionality for Log4j API support. + class GemFireLog4jApi < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Container + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar(jar_name, tomcat_lib, 'GemFire Log4j API') + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + private + + def jar_name + "log4j-api-#{@version}.jar" + end + end + + end +end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb new file mode 100644 index 0000000000..ad405b15e9 --- /dev/null +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb @@ -0,0 +1,53 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/container' +require 'java_buildpack/container/tomcat/tomcat_utils' +require 'java_buildpack/logging/logger_factory' + +module JavaBuildpack + module Container + + # Encapsulates the detect, compile, and release functionality for Log4j Core support. + class GemFireLog4jCore < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Container + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar(jar_name, tomcat_lib, 'GemFire Log4j Core') + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + private + + def jar_name + "log4j-core-#{@version}.jar" + end + end + + end +end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb new file mode 100644 index 0000000000..24aa0847d5 --- /dev/null +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb @@ -0,0 +1,53 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/container' +require 'java_buildpack/container/tomcat/tomcat_utils' +require 'java_buildpack/logging/logger_factory' + +module JavaBuildpack + module Container + + # Encapsulates the detect, compile, and release functionality for Log4j Jcl support. + class GemFireLog4jJcl < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Container + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar(jar_name, tomcat_lib, 'GemFire Log4j Jcl') + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + private + + def jar_name + "log4j-jcl-#{@version}.jar" + end + end + + end +end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb new file mode 100644 index 0000000000..10c35a679d --- /dev/null +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb @@ -0,0 +1,53 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/container' +require 'java_buildpack/container/tomcat/tomcat_utils' +require 'java_buildpack/logging/logger_factory' + +module JavaBuildpack + module Container + + # Encapsulates the detect, compile, and release functionality for Log4j Jul support. + class GemFireLog4jJul < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Container + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar(jar_name, tomcat_lib, 'GemFire Log4j Jul') + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + private + + def jar_name + "log4j-jul-#{@version}.jar" + end + end + + end +end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb new file mode 100644 index 0000000000..64d7228fc5 --- /dev/null +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb @@ -0,0 +1,53 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/container' +require 'java_buildpack/container/tomcat/tomcat_utils' +require 'java_buildpack/logging/logger_factory' + +module JavaBuildpack + module Container + + # Encapsulates the detect, compile, and release functionality for Log4j Slf4j Impl support. + class GemFireLog4jSlf4jImpl < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Container + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar(jar_name, tomcat_lib, 'GemFire Log4j Slf4j Impl') + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + private + + def jar_name + "log4j-slf4j-impl-#{@version}.jar" + end + end + + end +end diff --git a/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb b/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb index 7a5ee1ed9e..4aa05d7732 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb @@ -18,6 +18,11 @@ require 'java_buildpack/container' require 'java_buildpack/container/tomcat/tomcat_utils' require 'java_buildpack/container/tomcat/gemfire/gemfire' +require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_api' +require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_core' +require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl' +require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul' +require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl' require 'java_buildpack/container/tomcat/gemfire/gemfire_logging_api' require 'java_buildpack/container/tomcat/gemfire/gemfire_logging' require 'java_buildpack/container/tomcat/gemfire/gemfire_modules' @@ -48,6 +53,11 @@ def compile def sub_components(context) [ GemFire.new(sub_configuration_context(context, 'gemfire')), + GemFireLog4jApi.new(sub_configuration_context(context, 'gemfire_log4j_api')), + GemFireLog4jCore.new(sub_configuration_context(context, 'gemfire_log4j_core')), + GemFireLog4jJcl.new(sub_configuration_context(context, 'gemfire_log4j_jcl')), + GemFireLog4jJul.new(sub_configuration_context(context, 'gemfire_log4j_jul')), + GemFireLog4jSlf4jImpl.new(sub_configuration_context(context, 'gemfire_log4j_slf4j_impl')), GemFireLoggingApi.new(sub_configuration_context(context, 'gemfire_logging_api')), GemFireLogging.new(sub_configuration_context(context, 'gemfire_logging')), GemFireModules.new(sub_configuration_context(context, 'gemfire_modules')), diff --git a/spec/fixtures/stub-gemfire-log4j-api.jar b/spec/fixtures/stub-gemfire-log4j-api.jar new file mode 100644 index 0000000000000000000000000000000000000000..55f9148b703689892d3495fe53bc64bc8d4e2520 GIT binary patch literal 2658 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 Date: Thu, 11 Feb 2016 14:35:28 -0800 Subject: [PATCH 124/812] Copyright updates This change updates the copyright statements to 2016. --- .../copyright/Apache_License__Version_2_0.xml | 2 +- Rakefile | 2 +- bin/compile | 2 +- bin/detect | 2 +- bin/release | 2 +- lib/java_buildpack.rb | 2 +- lib/java_buildpack/buildpack.rb | 2 +- lib/java_buildpack/buildpack_version.rb | 2 +- lib/java_buildpack/component.rb | 2 +- .../component/additional_libraries.rb | 2 +- lib/java_buildpack/component/application.rb | 2 +- .../component/base_component.rb | 2 +- lib/java_buildpack/component/droplet.rb | 2 +- .../component/environment_variables.rb | 2 +- .../component/immutable_java_home.rb | 2 +- lib/java_buildpack/component/java_opts.rb | 2 +- .../component/modular_component.rb | 2 +- .../component/mutable_java_home.rb | 2 +- lib/java_buildpack/component/services.rb | 2 +- .../versioned_dependency_component.rb | 2 +- lib/java_buildpack/container.rb | 2 +- lib/java_buildpack/container/dist_zip.rb | 2 +- lib/java_buildpack/container/dist_zip_like.rb | 2 +- lib/java_buildpack/container/groovy.rb | 2 +- lib/java_buildpack/container/java_main.rb | 2 +- .../container/play_framework.rb | 2 +- lib/java_buildpack/container/ratpack.rb | 2 +- lib/java_buildpack/container/spring_boot.rb | 2 +- lib/java_buildpack/container/tomcat.rb | 2 +- .../container/tomcat/gemfire/gemfire.rb | 2 +- .../tomcat/gemfire/gemfire_log4j_api.rb | 2 +- .../tomcat/gemfire/gemfire_log4j_core.rb | 2 +- .../tomcat/gemfire/gemfire_log4j_jcl.rb | 2 +- .../tomcat/gemfire/gemfire_log4j_jul.rb | 2 +- .../gemfire/gemfire_log4j_slf4j_impl.rb | 2 +- .../tomcat/gemfire/gemfire_logging.rb | 2 +- .../tomcat/gemfire/gemfire_logging_api.rb | 2 +- .../tomcat/gemfire/gemfire_modules.rb | 2 +- .../tomcat/gemfire/gemfire_modules_tomcat7.rb | 2 +- .../tomcat/gemfire/gemfire_security.rb | 2 +- .../tomcat/tomcat_access_logging_support.rb | 2 +- .../container/tomcat/tomcat_gemfire_store.rb | 2 +- .../tomcat/tomcat_insight_support.rb | 2 +- .../container/tomcat/tomcat_instance.rb | 2 +- .../tomcat/tomcat_lifecycle_support.rb | 2 +- .../tomcat/tomcat_logging_support.rb | 2 +- .../container/tomcat/tomcat_redis_store.rb | 2 +- .../container/tomcat/tomcat_utils.rb | 2 +- lib/java_buildpack/framework.rb | 2 +- .../framework/app_dynamics_agent.rb | 2 +- lib/java_buildpack/framework/debug.rb | 2 +- .../framework/introscope_agent.rb | 2 +- lib/java_buildpack/framework/java_opts.rb | 2 +- lib/java_buildpack/framework/jmx.rb | 2 +- lib/java_buildpack/framework/jrebel_agent.rb | 2 +- lib/java_buildpack/framework/maria_db_jdbc.rb | 2 +- .../framework/new_relic_agent.rb | 2 +- .../play_framework_auto_reconfiguration.rb | 2 +- .../framework/play_framework_jpa_plugin.rb | 2 +- .../framework/postgresql_jdbc.rb | 2 +- .../framework/spring_auto_reconfiguration.rb | 2 +- .../web_xml_modifier.rb | 2 +- .../framework/spring_insight.rb | 2 +- .../framework/your_kit_profiler.rb | 2 +- lib/java_buildpack/jre.rb | 2 +- lib/java_buildpack/jre/open_jdk_jre.rb | 2 +- lib/java_buildpack/jre/open_jdk_like.rb | 2 +- lib/java_buildpack/jre/open_jdk_like_jre.rb | 2 +- .../jre/open_jdk_like_memory_calculator.rb | 2 +- lib/java_buildpack/jre/oracle_jre.rb | 2 +- lib/java_buildpack/logging.rb | 2 +- lib/java_buildpack/repository.rb | 2 +- .../repository/configured_item.rb | 2 +- .../repository/repository_index.rb | 2 +- .../repository/version_resolver.rb | 2 +- lib/java_buildpack/util.rb | 2 +- lib/java_buildpack/util/cache.rb | 2 +- .../util/cache/application_cache.rb | 2 +- .../util/cache/download_cache.rb | 2 +- .../util/cache/inferred_network_failure.rb | 2 +- lib/java_buildpack/util/class_file_utils.rb | 2 +- .../util/configuration_utils.rb | 2 +- lib/java_buildpack/util/constantize.rb | 2 +- lib/java_buildpack/util/dash_case.rb | 2 +- lib/java_buildpack/util/file_enumerable.rb | 2 +- .../util/find_single_directory.rb | 2 +- lib/java_buildpack/util/format_duration.rb | 2 +- lib/java_buildpack/util/groovy_utils.rb | 2 +- lib/java_buildpack/util/jar_finder.rb | 2 +- lib/java_buildpack/util/play.rb | 2 +- lib/java_buildpack/util/properties.rb | 2 +- lib/java_buildpack/util/qualify_path.rb | 2 +- lib/java_buildpack/util/ratpack_utils.rb | 2 +- lib/java_buildpack/util/shell.rb | 2 +- lib/java_buildpack/util/snake_case.rb | 2 +- lib/java_buildpack/util/space_case.rb | 2 +- lib/java_buildpack/util/spring_boot_utils.rb | 2 +- lib/java_buildpack/util/start_script.rb | 2 +- lib/java_buildpack/util/tokenized_version.rb | 2 +- resources/tomcat/conf/context.xml | 2 +- resources/tomcat/conf/logging.properties | 4 ++- resources/tomcat/conf/server.xml | 29 +++++++++-------- spec/application_helper.rb | 2 +- spec/bin/compile_spec.rb | 2 +- spec/bin/detect_spec.rb | 2 +- spec/bin/release_spec.rb | 2 +- spec/component_helper.rb | 2 +- spec/console_helper.rb | 2 +- spec/droplet_helper.rb | 2 +- .../container_groovy_logback/Alpha.java | 2 +- .../ch/qos/logback/pogo.groovy | 18 ++++++++++- .../container_groovy_main_method/Alpha.groovy | 2 +- .../Application.groovy | 2 +- .../directory/Beta.groovy | 2 +- .../container_groovy_non_pogo/Alpha.groovy | 2 +- .../Application.groovy | 2 +- .../logback.groovy | 2 +- .../container_groovy_shebang/Alpha.groovy | 2 +- .../Application.groovy | 2 +- .../Application.groovy | 2 +- .../Application.groovy | 2 +- .../application-root/app/Ratpack.groovy | 16 ++++++++++ .../app/ratpack.groovy | 16 ++++++++++ .../configuration.groovy | 16 ++++++++++ .../pogo_1.groovy | 18 ++++++++++- .../pogo.groovy | 18 ++++++++++- .../main.groovy | 18 ++++++++++- .../pogo.groovy | 18 ++++++++++- .../non_pogo.groovy | 18 ++++++++++- .../pogo.groovy | 18 ++++++++++- .../directory/pogo_4.groovy | 16 ++++++++++ .../pogo_1.groovy | 18 ++++++++++- .../pogo_2.groovy | 18 ++++++++++- .../pogo_3.groovy | 16 ++++++++++ .../.java-buildpack/tomcat/conf/context.xml | 2 +- .../.java-buildpack/tomcat/conf/server.xml | 30 +++++++++--------- ...ner_tomcat_gemfire_store_context_after.xml | 2 +- ...iner_tomcat_gemfire_store_server_after.xml | 31 +++++++++---------- .../.java-buildpack/tomcat/conf/context.xml | 2 +- ...ainer_tomcat_redis_store_context_after.xml | 2 +- .../container_tomcat_with_index/index.html | 16 ++++++++++ .../WEB-INF/web.xml | 16 ++++++++++ .../rebel-remote.xml | 16 ++++++++++ .../WEB-INF/classes/rebel-remote.xml | 16 ++++++++++ .../container/long_detect_tags.rb | 2 +- .../integration_valid/system.properties | 16 ++++++++++ spec/fixtures/test.properties | 16 ++++++++++ .../web_root_existing_params_after.xml | 15 +++++++++ .../web_root_existing_params_before.xml | 16 ++++++++++ ...eb_root_no_contextLoaderListener_after.xml | 15 +++++++++ ...b_root_no_contextLoaderListener_before.xml | 16 ++++++++++ spec/fixtures/web_root_no_params_after.xml | 15 +++++++++ spec/fixtures/web_root_no_params_before.xml | 16 ++++++++++ ...servlet_existing_load_on_startup_after.xml | 15 +++++++++ ...ervlet_existing_load_on_startup_before.xml | 16 ++++++++++ .../web_servlet_existing_params_after.xml | 15 +++++++++ .../web_servlet_existing_params_before.xml | 16 ++++++++++ .../web_servlet_load_on_startup_after.xml | 15 +++++++++ .../web_servlet_load_on_startup_before.xml | 16 ++++++++++ ...web_servlet_no_DispatcherServlet_after.xml | 15 +++++++++ ...eb_servlet_no_DispatcherServlet_before.xml | 16 ++++++++++ spec/fixtures/web_servlet_no_params_after.xml | 15 +++++++++ .../fixtures/web_servlet_no_params_before.xml | 16 ++++++++++ spec/integration_helper.rb | 2 +- spec/internet_availability_helper.rb | 2 +- spec/java_buildpack/buildpack_spec.rb | 2 +- spec/java_buildpack/buildpack_version_spec.rb | 2 +- .../component/additional_libraries_spec.rb | 2 +- .../component/application_spec.rb | 2 +- .../component/base_component_spec.rb | 2 +- spec/java_buildpack/component/droplet_spec.rb | 2 +- .../component/environment_variables_spec.rb | 2 +- .../component/immutable_java_home_spec.rb | 2 +- .../component/java_opts_spec.rb | 2 +- .../component/modular_component_spec.rb | 2 +- .../component/mutable_java_home_spec.rb | 2 +- .../java_buildpack/component/services_spec.rb | 2 +- .../versioned_dependency_component_spec.rb | 2 +- .../container/dist_zip_like_spec.rb | 2 +- .../java_buildpack/container/dist_zip_spec.rb | 2 +- spec/java_buildpack/container/groovy_spec.rb | 2 +- .../container/java_main_spec.rb | 2 +- .../container/play_framework_spec.rb | 2 +- spec/java_buildpack/container/ratpack_spec.rb | 2 +- .../container/spring_boot_cli_spec.rb | 2 +- .../container/spring_boot_spec.rb | 2 +- .../tomcat/gemfire/gemfire_log4j_api_spec.rb | 2 +- .../tomcat/gemfire/gemfire_log4j_core_spec.rb | 2 +- .../tomcat/gemfire/gemfire_log4j_jcl_spec.rb | 2 +- .../tomcat/gemfire/gemfire_log4j_jul_spec.rb | 2 +- .../gemfire/gemfire_log4j_slf4j_impl_spec.rb | 2 +- .../gemfire/gemfire_logging_api_spec.rb | 2 +- .../tomcat/gemfire/gemfire_logging_spec.rb | 2 +- .../tomcat/gemfire/gemfire_modules_spec.rb | 2 +- .../gemfire/gemfire_modules_tomcat7_spec.rb | 2 +- .../tomcat/gemfire/gemfire_security_spec.rb | 2 +- .../container/tomcat/gemfire/gemfire_spec.rb | 2 +- .../tomcat_access_logging_support_spec.rb | 2 +- .../tomcat/tomcat_gemfire_store_spec.rb | 2 +- .../tomcat/tomcat_insight_support_spec.rb | 2 +- .../container/tomcat/tomcat_instance_spec.rb | 2 +- .../tomcat/tomcat_lifecycle_support_spec.rb | 2 +- .../tomcat/tomcat_logging_support_spec.rb | 2 +- .../tomcat/tomcat_redis_store_spec.rb | 2 +- spec/java_buildpack/container/tomcat_spec.rb | 2 +- .../framework/app_dynamics_agent_spec.rb | 2 +- spec/java_buildpack/framework/debug_spec.rb | 2 +- .../framework/introscope_agent_spec.rb | 2 +- .../framework/java_opts_spec.rb | 2 +- spec/java_buildpack/framework/jmx_spec.rb | 2 +- .../framework/jrebel_agent_spec.rb | 2 +- .../framework/maria_db_jdbc_spec.rb | 2 +- .../framework/new_relic_agent_spec.rb | 2 +- ...lay_framework_auto_reconfiguration_spec.rb | 2 +- .../play_framework_jpa_plugin_spec.rb | 2 +- .../framework/postgresql_jdbc_spec.rb | 2 +- .../web_xml_modifier_spec.rb | 2 +- .../spring_auto_reconfiguration_spec.rb | 2 +- .../framework/spring_insight_spec.rb | 2 +- .../framework/your_kit_profiler_spec.rb | 2 +- .../jre/open_jdk_like_jre_spec.rb | 2 +- .../open_jdk_like_memory_calculator_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_spec.rb | 2 +- .../logging/delegating_logger_spec.rb | 2 +- .../repository/configured_item_spec.rb | 2 +- .../repository/repository_index_spec.rb | 2 +- .../repository/version_resolver_spec.rb | 2 +- .../util/cache/application_cache_spec.rb | 2 +- .../util/cache/cached_file_spec.rb | 2 +- .../util/cache/download_cache_spec.rb | 2 +- .../util/cache/internet_availability_spec.rb | 2 +- .../util/cache/yield_file_with_content.rb | 2 +- .../util/configuration_utils_spec.rb | 2 +- spec/java_buildpack/util/constantize_spec.rb | 2 +- .../util/format_duration_spec.rb | 2 +- spec/java_buildpack/util/play/base_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_spec.rb | 2 +- spec/java_buildpack/util/properties_spec.rb | 2 +- spec/java_buildpack/util/shell_spec.rb | 2 +- .../util/tokenized_version_spec.rb | 2 +- spec/logging_helper.rb | 2 +- spec/memory_limit_helper.rb | 2 +- spec/spec_helper.rb | 2 +- 243 files changed, 827 insertions(+), 259 deletions(-) diff --git a/.idea/copyright/Apache_License__Version_2_0.xml b/.idea/copyright/Apache_License__Version_2_0.xml index b07dfd5502..893ada61a7 100644 --- a/.idea/copyright/Apache_License__Version_2_0.xml +++ b/.idea/copyright/Apache_License__Version_2_0.xml @@ -1,6 +1,6 @@ - - + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 4b1ec9f41a..e80b43be78 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -5,5 +5,4 @@ - - + \ No newline at end of file diff --git a/java-buildpack.iml b/java-buildpack.iml index 33ec999a40..ec50298002 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -266,37 +266,36 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + From dcfaa84019ad6cdedc5ea124bab57fe8482e18b3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 21 Mar 2016 06:26:00 -0700 Subject: [PATCH 158/812] Improved Diagnostics Previously, the buildpack only debug logged the status of each HTTP response made by the DownloadCache. Currently we're diagnosing a problem that required viewing the headers for each response. This change adds a log statement containing all of the response headers. --- lib/java_buildpack/util/cache/download_cache.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index ad39018d29..5816d12498 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -123,7 +123,8 @@ def attempt(http, request, cached_file) downloaded = false http.request request do |response| - @logger.debug { "Status: #{response.code}" } + @logger.debug { "Response headers: #{response.to_hash}"} + @logger.debug { "Response status: #{response.code}" } if response.is_a? Net::HTTPOK cache_etag response, cached_file From 0cfa3df7bad53c0ff8438cf5f604411c092b7aaf Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 21 Mar 2016 06:38:55 -0700 Subject: [PATCH 159/812] Rubocop Fixes This change updates the code to make Rubocop happy. --- .rubocop.yml | 2 +- lib/java_buildpack/util/cache/download_cache.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 48a6803521..9c8529d8dd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -17,7 +17,7 @@ Metrics/CyclomaticComplexity: Metrics/LineLength: Max: 120 Metrics/MethodLength: - Max: 17 + Max: 18 Metrics/ParameterLists: Max: 6 Metrics/PerceivedComplexity: diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 5816d12498..304ead6a59 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -123,7 +123,7 @@ def attempt(http, request, cached_file) downloaded = false http.request request do |response| - @logger.debug { "Response headers: #{response.to_hash}"} + @logger.debug { "Response headers: #{response.to_hash}" } @logger.debug { "Response status: #{response.code}" } if response.is_a? Net::HTTPOK From a3caeff96e0d6b8e5d4e22dd7557c68b73e55b89 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 21 Mar 2016 08:07:43 -0700 Subject: [PATCH 160/812] Handle Encoded Downloads Previously, all downloads passed through DownloadCache required that the value of the Content-Length header matched the size of the file that was actually downloaded. This did not take into account compressed encoding schemes for the artifacts and would fail when they were compressed. This change detects when an artifact is compressed and skips the size validation. [#116036875] --- lib/java_buildpack/util/cache/download_cache.rb | 10 ++++++++-- .../java_buildpack/util/cache/download_cache_spec.rb | 12 ++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 304ead6a59..f760dedb41 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -144,6 +144,8 @@ def attempt(http, request, cached_file) end def cache_content(response, cached_file) + compressed = compressed?(response) + cached_file.cached(File::CREAT | File::WRONLY | File::BINARY) do |f| @logger.debug { "Persisting content to #{f.path}" } @@ -152,7 +154,7 @@ def cache_content(response, cached_file) f.fsync end - validate_size response['Content-Length'], cached_file + validate_size response['Content-Length'], cached_file unless compressed end def cache_etag(response, cached_file) @@ -183,6 +185,10 @@ def cache_last_modified(response, cached_file) end end + def compressed?(response) + %w(br compress deflate gzip x-gzip).include?(response['Content-Encoding']) + end + def debug_ssl(http) socket = http.instance_variable_get('@socket') return unless socket @@ -300,7 +306,7 @@ def validate_size(expected_size, cached_file) actual_size = cached_file.cached(File::RDONLY) { |f| f.size } @logger.debug { "Validated content size #{actual_size} is #{expected_size}" } - return if expected_size.to_i == actual_size + return if (expected_size.to_i == actual_size) cached_file.destroy fail InferredNetworkFailure, "Content has invalid size. Was #{actual_size}, should be #{expected_size}." diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 0d79b4a66e..81dfbc7222 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -170,6 +170,18 @@ expect { |b| download_cache.get uri, &b }.to yield_file_with_content(/foo-cached/) end + it 'ignores incorrect size when encoded' do + stub_request(:get, uri) + .to_return(status: 200, body: 'foo-cac', headers: { Etag: 'foo-etag', + 'Content-Encoding' => 'gzip', + 'Last-Modified' => 'foo-last-modified', + 'Content-Length' => 10 }) + + touch immutable_cache_root, 'cached', 'old-foo-cached' + + expect { |b| download_cache.get uri, &b }.to yield_file_with_content(/foo-cac/) + end + context do let(:environment) { { 'http_proxy' => 'http://proxy:9000', 'HTTP_PROXY' => nil } } From b7ed6520903b853ce2f298c93a00893abbf4a8f6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 22 Mar 2016 15:25:08 -0700 Subject: [PATCH 161/812] Container Customizer With a recent update to the Spring Boot support in the buildpack, Spring Boot WARs were broken. The root cause is that the embedded Tomcat container would not allow additional libraries to be symbolically linked to the WEB-INF directory. This change adds a framework that notices that the application is a Spring Boot WAR and contributes a Tomcat LifecycleListener that adjusts this configuration. --- README.md | 1 + config/components.yml | 1 + config/container_customizer.yml | 19 ++++++ docs/framework-container_customizer.md | 30 +++++++++ .../framework/container_customizer.rb | 58 ++++++++++++++++++ .../META-INF/MANIFEST.MF | 4 ++ .../WEB-INF/lib/.gitignore | 0 spec/fixtures/stub-container-customizer.jar | Bin 0 -> 341 bytes .../framework/container_customizer_spec.rb | 52 ++++++++++++++++ 9 files changed, 165 insertions(+) create mode 100644 config/container_customizer.yml create mode 100644 docs/framework-container_customizer.md create mode 100644 lib/java_buildpack/framework/container_customizer.rb create mode 100644 spec/fixtures/framework_container_customizer/META-INF/MANIFEST.MF create mode 100644 spec/fixtures/framework_container_customizer/WEB-INF/lib/.gitignore create mode 100644 spec/fixtures/stub-container-customizer.jar create mode 100644 spec/java_buildpack/framework/container_customizer_spec.rb diff --git a/README.md b/README.md index 9490e54ce7..6a49f5cab9 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) * [Container Certificate Trust Store](docs/framework-container_certificate_trust_store.md) ([Configuration](docs/framework-container_certificate_trust_store.md#configuration)) + * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) * [DynaTrace Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 095a9e971b..06bdbcd4c8 100644 --- a/config/components.yml +++ b/config/components.yml @@ -37,6 +37,7 @@ jres: frameworks: # - "JavaBuildpack::Framework::AppDynamicsAgent" - "JavaBuildpack::Framework::ContainerCertificateTrustStore" + - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::Debug" # - "JavaBuildpack::Framework::DynaTraceAgent" # - "JavaBuildpack::Framework::IntroscopeAgent" diff --git a/config/container_customizer.yml b/config/container_customizer.yml new file mode 100644 index 0000000000..291472d8ee --- /dev/null +++ b/config/container_customizer.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Container Customizer framework +--- +version: 1.+ +repository_root: "{default.repository.root}/container-customizer" diff --git a/docs/framework-container_customizer.md b/docs/framework-container_customizer.md new file mode 100644 index 0000000000..20daab9f3f --- /dev/null +++ b/docs/framework-container_customizer.md @@ -0,0 +1,30 @@ +# Container Customizer Framework +The Container Customizer Framework modifies the configuration of an embedded Tomcat container in a Spring Boot WAR file. + + + + + + + + + + +
Detection CriterionApplication is a Spring Boot WAR file
Tagscontainer-customizer=<version>
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/container_customizer.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the MariaDB JDBC repository index ([details][repositories]). +| `version` | The version of MariaDB JDBC to use. Candidate versions can be found in [this listing][]. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[`config/container_customizer.yml`]: ../config/container_customizer.yml +[repositories]: extending-repositories.md +[this listing]: http://download.pivotal.io.s3.amazonaws.com/container-customizer/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/container_customizer.rb b/lib/java_buildpack/framework/container_customizer.rb new file mode 100644 index 0000000000..f4fe7dd413 --- /dev/null +++ b/lib/java_buildpack/framework/container_customizer.rb @@ -0,0 +1,58 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/spring_boot_utils' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for customizing a Spring Boot container. + class ContainerCustomizer < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + spring_boot? && war? + end + + private + + def spring_boot? + JavaBuildpack::Util::SpringBootUtils.new.is?(@application) + end + + def war? + (@droplet.root + 'WEB-INF/lib').exist? + end + + end + + end +end diff --git a/spec/fixtures/framework_container_customizer/META-INF/MANIFEST.MF b/spec/fixtures/framework_container_customizer/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..18573ddd34 --- /dev/null +++ b/spec/fixtures/framework_container_customizer/META-INF/MANIFEST.MF @@ -0,0 +1,4 @@ +Spring-Boot-Lib: WEB-INF/lib/ +Spring-Boot-Version: 1.3.3.RELEASE +Main-Class: org.springframework.boot.loader.WarLauncher + diff --git a/spec/fixtures/framework_container_customizer/WEB-INF/lib/.gitignore b/spec/fixtures/framework_container_customizer/WEB-INF/lib/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/stub-container-customizer.jar b/spec/fixtures/stub-container-customizer.jar new file mode 100644 index 0000000000000000000000000000000000000000..0878c3ccb50e0696f38ae356e9854c75199158f3 GIT binary patch literal 341 zcmWIWW@Zs#;Nak3$ZLM$#DD}i8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1gx0>v$BCyF#%yMkUj+BFaQAGLPY%l literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/container_customizer_spec.rb b/spec/java_buildpack/framework/container_customizer_spec.rb new file mode 100644 index 0000000000..eaf02f38e6 --- /dev/null +++ b/spec/java_buildpack/framework/container_customizer_spec.rb @@ -0,0 +1,52 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/container_customizer' + +describe JavaBuildpack::Framework::ContainerCustomizer do + include_context 'component_helper' + + it 'does not detect without Spring Boot WAR' do + expect(component.detect).to be_nil + end + + it 'detects with Spring Boot WAR', + app_fixture: 'framework_container_customizer' do + + expect(component.detect).to eq("container-customizer=#{version}") + end + + it 'downloads the container customizer', + app_fixture: 'framework_container_customizer', + cache_fixture: 'stub-container-customizer.jar' do + + component.compile + + expect(sandbox + "container_customizer-#{version}.jar").to exist + end + + it 'adds container customizer to the additional libraries', + app_fixture: 'framework_container_customizer', + cache_fixture: 'stub-container-customizer.jar' do + + component.release + + expect(additional_libraries).to include(sandbox + "container_customizer-#{version}.jar") + end + +end From b885b0f1a3926fbc5a77212bae228694f6b183aa Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 24 Mar 2016 13:44:22 -0700 Subject: [PATCH 162/812] Client Certificate Authentication This change updates the DownloadCache such that it will read a client certificate, private key, and associate password and use them for SSL client certificate authentication for all requests. [#116145431] --- .rubocop.yml | 2 +- config/cache.yml | 4 +++ docs/extending-caches.md | 3 ++ .../util/cache/download_cache.rb | 34 +++++++++++++++---- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9c8529d8dd..e6604347e0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -11,7 +11,7 @@ AllCops: Metrics/AbcSize: Max: 22 Metrics/ClassLength: - Max: 200 + Max: 250 Metrics/CyclomaticComplexity: Max: 10 Metrics/LineLength: diff --git a/config/cache.yml b/config/cache.yml index 30a440c561..cd4384a806 100644 --- a/config/cache.yml +++ b/config/cache.yml @@ -16,3 +16,7 @@ # Download cache configuration --- remote_downloads: enabled +client_authentication: + certificate_location: + private_key_location: + private_key_password: diff --git a/docs/extending-caches.md b/docs/extending-caches.md index 0b41c7b50d..0489516005 100644 --- a/docs/extending-caches.md +++ b/docs/extending-caches.md @@ -46,6 +46,9 @@ Caching can be configured by modifying the [`config/cache.yml`][] file in the bu | Name | Description | ---- | ----------- | `remote_downloads` | This property can take the value `enabled` or `disabled`.

The default value of `enabled` means that the buildpack will check the internet connection and remember the result for the remainder of the buildpack invocation. If the internet is available, it will then be used to download files. If the internet is not available, cache will be consulted instead.

Alternatively, the property may be set to `disabled` which avoids the check for an internet connection, does not attempt downloads, and consults the cache instead. +| `client_authentication.certificate_location` | The path to a PEM or DER encoded certificate to use for SSL client certificate authentication +| `client_authentication.private_key_location` | The path to a PEM or DER encoded DSA or RSA private key to use for SSL client certificate authentication +| `client_authentication.private_key_password` | The password for the private key to use for SSL client certificate authentication ## `JavaBuildpack::Util::Cache::DownloadCache` The [`DownloadCache`][] is the most generic of the two caches. It allows you to create a cache that persists files any that write access is available. The constructor signature looks the following: diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index f760dedb41..75888247c5 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -19,9 +19,11 @@ require 'java_buildpack/util/cache/cached_file' require 'java_buildpack/util/cache/inferred_network_failure' require 'java_buildpack/util/cache/internet_availability' +require 'java_buildpack/util/configuration_utils' require 'java_buildpack/util/sanitizer' require 'monitor' require 'net/http' +require 'openssl' require 'pathname' require 'tmpdir' require 'uri' @@ -136,13 +138,19 @@ def attempt(http, request, cached_file) elsif redirect?(response) downloaded = update URI(response['Location']), cached_file else - fail InferredNetworkFailure, "Bad response: #{response}" + fail InferredNetworkFailure, "#{response.code} #{response.message}\n#{response.body}" end end downloaded end + def ca_file(http_options) + return unless CA_FILE.exist? + http_options[:ca_file] = CA_FILE.to_s + @logger.debug { "Adding additional CA certificates from #{CA_FILE}" } + end + def cache_content(response, cached_file) compressed = compressed?(response) @@ -185,6 +193,22 @@ def cache_last_modified(response, cached_file) end end + def client_authentication(http_options) + client_authentication = JavaBuildpack::Util::ConfigurationUtils.load('cache')['client_authentication'] + + certificate_location = client_authentication['certificate_location'] + File.open(certificate_location) do |f| + http_options[:cert] = OpenSSL::X509::Certificate.new f.read + @logger.debug { "Adding client certificate from #{certificate_location}" } + end if certificate_location + + private_key_location = client_authentication['private_key_location'] + File.open(private_key_location) do |f| + http_options[:key] = OpenSSL::PKey.read f.read, client_authentication['private_key_password'] + @logger.debug { "Adding private key from #{private_key_location}" } + end if private_key_location + end + def compressed?(response) %w(br compress deflate gzip x-gzip).include?(response['Content-Encoding']) end @@ -230,10 +254,8 @@ def http_options(rich_uri) http_options[:use_ssl] = true @logger.debug { 'Adding HTTP options for secure connection' } - if CA_FILE.exist? - http_options[:ca_file] = CA_FILE.to_s - @logger.debug { "Adding additional certs from #{CA_FILE}" } - end + ca_file http_options + client_authentication http_options end http_options @@ -294,7 +316,7 @@ def attempt_update(cached_file, http, uri) InternetAvailability.instance.available false, "Request failed: #{e.message}" raise e else - @logger.warn { "Request failure #{failures}, retrying: #{e.message}" } + @logger.warn { "Request failure #{failures}, retrying. Failure: #{e.message}" } retry end end From ded4a0fbc9ccfff9f03459c5d0da58c3c5c5d156 Mon Sep 17 00:00:00 2001 From: Alois Mayr Date: Fri, 1 Apr 2016 08:54:29 +0200 Subject: [PATCH 163/812] Deploy Complete Ruxit Agent ZIP Previously, the agent zip that was downloaded by the Ruxit framework contained more content than was required by running applications. Because of this, it was filtered to remove unnecessary content. Recent versions of the agent ZIP file now contain only what is required by the application and therefore this filtering is unneeded. By removing this filtering it also makes it possible to change the required contents of the agent without requiring a change to the buildpack. [resolves #286] --- lib/java_buildpack/framework/ruxit_agent.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/java_buildpack/framework/ruxit_agent.rb b/lib/java_buildpack/framework/ruxit_agent.rb index f6a6a9c5dc..bfb452028a 100644 --- a/lib/java_buildpack/framework/ruxit_agent.rb +++ b/lib/java_buildpack/framework/ruxit_agent.rb @@ -121,10 +121,8 @@ def tenanttoken(credentials) end def unpack_agent(root) - FileUtils.mkdir_p(agent_dir) - FileUtils.mv(root + 'agent/bin', agent_dir) - FileUtils.mv(root + 'agent/conf', agent_dir) - FileUtils.mv(root + 'agent/lib64', agent_dir) + FileUtils.mkdir_p(@droplet.sandbox) + FileUtils.mv(root + 'agent', @droplet.sandbox) end end From a8e2f228f497f3ceeeb92b435860b6e17ef58089 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 5 Apr 2016 17:37:26 -0700 Subject: [PATCH 164/812] Move Docker Image --- ci/docker-image/Dockerfile | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 ci/docker-image/Dockerfile diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile new file mode 100644 index 0000000000..b589681a51 --- /dev/null +++ b/ci/docker-image/Dockerfile @@ -0,0 +1,39 @@ +FROM ubuntu:trusty + +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + git \ + libssl-dev \ + libreadline-dev \ + python \ + zip \ + zlib1g-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN locale-gen en_US.UTF-8 \ + && /usr/sbin/update-locale LANG=en_US.UTF-8 \ + && dpkg-reconfigure -f noninteractive locales + +RUN git clone https://github.com/rbenv/rbenv.git $HOME/.rbenv \ + && cd $HOME/.rbenv \ + && src/configure \ + && make -C src \ + && ln -s $HOME/.rbenv/bin/rbenv /usr/local/bin + +RUN eval "$(rbenv init -)" \ + && git clone https://github.com/rbenv/ruby-build.git $(rbenv root)/plugins/ruby-build + +RUN eval "$(rbenv init -)" \ + && git clone https://github.com/sstephenson/rbenv-default-gems.git $(rbenv root)/plugins/rbenv-default-gems \ + && echo 'bundler' >> $(rbenv root)/default-gems + +RUN eval "$(rbenv init -)" \ + && rbenv install 1.9.3-p551 + +RUN eval "$(rbenv init -)" \ +&& rbenv install 2.2.4 + +RUN eval "$(rbenv init -)" \ +&& rbenv install 2.3.0 From c2d165d87813d81b596e21928ce2b07dbcc0b711 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 8 Apr 2016 09:06:53 -0700 Subject: [PATCH 165/812] More Lenient Version Resolution Previously, version resolution with the contents of repository indexes was strict. If there was an illegal version, all resolution would stop; in other words, the buildpack would cease to function. This recently became an issue for the first time when a third-party repository added an invalid version number to their index breaking all users of the buildpack. This change updates the version resolution logic to ignore and warn on a bad version instead of failing. [#290] --- lib/java_buildpack/repository/version_resolver.rb | 13 ++++++++++--- .../repository/version_resolver_spec.rb | 8 +++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/repository/version_resolver.rb b/lib/java_buildpack/repository/version_resolver.rb index d7584bb12c..a9bba1967c 100644 --- a/lib/java_buildpack/repository/version_resolver.rb +++ b/lib/java_buildpack/repository/version_resolver.rb @@ -16,6 +16,7 @@ require 'java_buildpack/repository' require 'java_buildpack/util/tokenized_version' +require 'java_buildpack/logging/logger_factory' module JavaBuildpack module Repository @@ -38,9 +39,7 @@ class << self # @return [TokenizedVersion] the resolved version or nil if no matching version is found def resolve(candidate_version, versions) tokenized_candidate_version = safe_candidate_version candidate_version - tokenized_versions = versions.map do |version| - JavaBuildpack::Util::TokenizedVersion.new(version, false) - end + tokenized_versions = versions.map { |version| create_token(version) }.compact version = tokenized_versions .select { |tokenized_version| matches? tokenized_candidate_version, tokenized_version } @@ -55,6 +54,14 @@ def resolve(candidate_version, versions) private_constant :TOKENIZED_WILDCARD + def create_token(version) + JavaBuildpack::Util::TokenizedVersion.new(version, false) + rescue StandardError => e + logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger VersionResolver + logger.warn { "Discarding illegal version #{version}: #{e.message}" } + nil + end + def safe_candidate_version(candidate_version) if candidate_version.nil? TOKENIZED_WILDCARD diff --git a/spec/java_buildpack/repository/version_resolver_spec.rb b/spec/java_buildpack/repository/version_resolver_spec.rb index c3014ce450..f4463a013b 100644 --- a/spec/java_buildpack/repository/version_resolver_spec.rb +++ b/spec/java_buildpack/repository/version_resolver_spec.rb @@ -14,13 +14,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +require 'logging_helper' require 'spec_helper' require 'java_buildpack/repository/version_resolver' require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Repository::VersionResolver do + include_context 'logging_helper' - let(:versions) { %w(1.6.0_26 1.6.0_27 1.6.1_14 1.7.0_19 1.7.0_21 1.8.0_M-7 1.8.0_05 2.0.0) } + let(:versions) { %w(1.6.0_26 1.6.0_27 1.6.1_14 1.7.0_19 1.7.0_21 1.8.0_M-7 1.8.0_05 2.0.0 2.0.0a) } it 'resolves the default version if no candidate is supplied' do expect(described_class.resolve(nil, versions)).to eq(tokenized_version('2.0.0')) @@ -56,8 +58,8 @@ expect(described_class.resolve(tokenized_version('2.1.0'), versions)).to be_nil end - it 'raises an exception when a wildcard is specified in the [] collection' do - expect { described_class.resolve(tokenized_version('1.6.0_25'), %w(+)) }.to raise_error(/Invalid/) + it 'ignores illegal versions' do + expect(described_class.resolve(tokenized_version('2.0.+'), versions)).to eq(tokenized_version('2.0.0')) end def tokenized_version(s) From 630fe906cec23ac857539a5944d4312a435babc8 Mon Sep 17 00:00:00 2001 From: akirasoft Date: Wed, 6 Apr 2016 23:22:05 +0000 Subject: [PATCH 166/812] Enable Dynatrace 6.3 Agent and public repo Added public repository containing Dynatrace Agent 6.3 and incremented agent version to 6.3. [resolves #289] --- config/components.yml | 2 +- config/dyna_trace_agent.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/components.yml b/config/components.yml index 06bdbcd4c8..5289aefa50 100644 --- a/config/components.yml +++ b/config/components.yml @@ -39,7 +39,7 @@ frameworks: - "JavaBuildpack::Framework::ContainerCertificateTrustStore" - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::Debug" -# - "JavaBuildpack::Framework::DynaTraceAgent" + - "JavaBuildpack::Framework::DynaTraceAgent" # - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::Jmx" - "JavaBuildpack::Framework::JrebelAgent" diff --git a/config/dyna_trace_agent.yml b/config/dyna_trace_agent.yml index d8e9e3fb1a..4d3e4e6616 100644 --- a/config/dyna_trace_agent.yml +++ b/config/dyna_trace_agent.yml @@ -15,6 +15,6 @@ # Configuration for the Dynatrace framework --- -version: 6.1.0_+ -repository_root: "" +version: 6.3.0_+ +repository_root: "http://downloads.dynatracesaas.com/cloudfoundry/buildpack/java" default_agent_name: From fa50848030fad5d20a9507ff4680eadbf65fb8b0 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 14 Apr 2016 14:12:56 -0700 Subject: [PATCH 167/812] Polishing --- docs/framework-container_customizer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/framework-container_customizer.md b/docs/framework-container_customizer.md index 20daab9f3f..97538ea05e 100644 --- a/docs/framework-container_customizer.md +++ b/docs/framework-container_customizer.md @@ -20,8 +20,8 @@ The framework can be configured by modifying the [`config/container_customizer.y | Name | Description | ---- | ----------- -| `repository_root` | The URL of the MariaDB JDBC repository index ([details][repositories]). -| `version` | The version of MariaDB JDBC to use. Candidate versions can be found in [this listing][]. +| `repository_root` | The URL of the Container Customizer repository index ([details][repositories]). +| `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. [Configuration and Extension]: ../README.md#configuration-and-extension [`config/container_customizer.yml`]: ../config/container_customizer.yml From 69616118e43cc0c07b4f9c3fdcaa2c27e3688e2d Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 20 Apr 2016 13:24:14 -0700 Subject: [PATCH 168/812] Reinstate AppDynamics Agent Now that we can once again download the latest versions of the AppDynamics agent, it is reinstated. --- config/components.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/components.yml b/config/components.yml index 5289aefa50..453c574c8e 100644 --- a/config/components.yml +++ b/config/components.yml @@ -35,7 +35,7 @@ jres: # command after any Java Opts added by previous frameworks. frameworks: -# - "JavaBuildpack::Framework::AppDynamicsAgent" + - "JavaBuildpack::Framework::AppDynamicsAgent" - "JavaBuildpack::Framework::ContainerCertificateTrustStore" - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::Debug" From b07524d25e94117317fbd873a10a0cb738f908f1 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 20 Apr 2016 13:44:14 -0700 Subject: [PATCH 169/812] Polishing This change polishes up the buildpack before release --- config/dyna_trace_agent.yml | 4 ++-- config/tomcat.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/dyna_trace_agent.yml b/config/dyna_trace_agent.yml index 4d3e4e6616..57e11c110a 100644 --- a/config/dyna_trace_agent.yml +++ b/config/dyna_trace_agent.yml @@ -16,5 +16,5 @@ # Configuration for the Dynatrace framework --- version: 6.3.0_+ -repository_root: "http://downloads.dynatracesaas.com/cloudfoundry/buildpack/java" -default_agent_name: +repository_root: http://downloads.dynatracesaas.com/cloudfoundry/buildpack/java +default_agent_name: diff --git a/config/tomcat.yml b/config/tomcat.yml index 1660a40520..7f9959f2b0 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -18,11 +18,11 @@ tomcat: version: 8.0.+ repository_root: "{default.repository.root}/tomcat" - context_path: + context_path: external_configuration_enabled: false external_configuration: version: 1.+ - repository_root: + repository_root: lifecycle_support: version: 2.+ repository_root: "{default.repository.root}/tomcat-lifecycle-support" From 538d546983b8778ea3027f35488da2a25a709e1a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 21 Apr 2016 10:20:48 -0700 Subject: [PATCH 170/812] Exclude Precise from Packaging Previously, the offline packaging build downloaded platform-specific dependencies for Mountain Lion, Precise, and Trusty. As Precise is no longer a supported platform, this change removes it from that list, shrinking the size of the offline packaged buildpack. --- rakelib/package.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/package.rb b/rakelib/package.rb index 27572fb0a1..4ba2adf63b 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -32,7 +32,7 @@ def self.version BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze - PLATFORMS = %w(mountainlion precise trusty).freeze + PLATFORMS = %w(mountainlion trusty).freeze STAGING_DIR = "#{BUILD_DIR}/staging".freeze From 78c3d0a273cba54fa8ed63238eadde39c1e13ff9 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 21 Apr 2016 10:24:31 -0700 Subject: [PATCH 171/812] Loosen AppDynamics Versions This change loosens the version range of the AppDynamics agent. --- config/app_dynamics_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 1f1f7af838..99633c878f 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -15,7 +15,7 @@ # Configuration for the AppDynamics framework --- -version: 4.1.+ +version: 4.+ repository_root: "{default.repository.root}/app-dynamics" default_application_name: default_node_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); From 7feb6c5bbe38852313be578be50e2f932ace3d90 Mon Sep 17 00:00:00 2001 From: Alois Mayr Date: Tue, 17 May 2016 10:47:27 +0200 Subject: [PATCH 172/812] Add support section to Dynatrace Ruxit documentation & moved default repo to HTTPS --- README.md | 3 ++- config/ruxit_agent.yml | 2 +- docs/framework-ruxit_agent.md | 13 +++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6a49f5cab9..af73808742 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,8 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Container Certificate Trust Store](docs/framework-container_certificate_trust_store.md) ([Configuration](docs/framework-container_certificate_trust_store.md#configuration)) * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) - * [DynaTrace Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) + * [Dynatrace Application Monitoring Agent](docs/framework-dyna_trace_agent.md) ([Configuration](docs/framework-dyna_trace_agent.md#configuration)) + * [Dynatrace Ruxit Cloud Native Agent](docs/framework-ruxit_agent.md) ([Configuration](docs/framework-ruxit_agent.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) diff --git a/config/ruxit_agent.yml b/config/ruxit_agent.yml index c1dba49eda..352f13b895 100644 --- a/config/ruxit_agent.yml +++ b/config/ruxit_agent.yml @@ -16,4 +16,4 @@ # Configuration for the Ruxit framework --- version: 1.+ -repository_root: http://download.ruxit.com/agent/paas/cloudfoundry/java +repository_root: https://download.ruxit.com/agent/paas/cloudfoundry/java diff --git a/docs/framework-ruxit_agent.md b/docs/framework-ruxit_agent.md index e56212c057..46c3199e31 100644 --- a/docs/framework-ruxit_agent.md +++ b/docs/framework-ruxit_agent.md @@ -1,4 +1,6 @@ -# Ruxit Agent Framework +[Dynatrace Ruxit](http://www.dynatrace.com/en/ruxit/) is your full stack monitoring solution - powered by artificial intelligence. Dynatrace Ruxit allows you insights into all application requests from the users click in the browser down to the database statement and code-level. + +# Dynatrace Ruxit Agent Framework The Ruxit Agent Framework causes an application to be automatically configured to work with a bound [Ruxit Service][] instance (Free trials available). @@ -16,7 +18,7 @@ The Ruxit Agent Framework causes an application to be automatically configured t
Tags are printed to standard output by the buildpack detect script -## User-Provided Service (Optional) +## User-Provided Service Users may optionally provide their own Ruxit service. A user-provided Ruxit service must have a name or tag with `ruxit` in it so that the Ruxit Agent Framework will automatically configure the application to work with the service. The credential payload of the service may contain the following entries: @@ -39,9 +41,12 @@ The framework can be configured by modifying the [`config/ruxit_agent.yml`][] fi | `repository_root` | The URL of the Ruxit repository index ([details][repositories]). | `version` | The version of Ruxit to use. Candidate versions can be found in [this listing][]. +## Support +This buildpack is currently Beta. If you have any questions or problems regarding the build pack itself please don't hesitate to contact Dynatrace Ruxit on https://answers.ruxit.com/, be sure to use "cloudfoundry" as a topic. + [Configuration and Extension]: ../README.md#configuration-and-extension [`config/ruxit_agent.yml`]: ../config/ruxit_agent.yml -[Ruxit Service]: https://ruxit.com +[Ruxit Service]: http://www.dynatrace.com/en/ruxit/ [repositories]: extending-repositories.md -[this listing]: http://download.ruxit.com/agent/paas/cloudfoundry/java/index.yml +[this listing]: https://download.ruxit.com/agent/paas/cloudfoundry/java/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering From ab5d8bfd46cc14180c1526cfce36d97622d99270 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 17 May 2016 06:02:38 -0700 Subject: [PATCH 173/812] Polishing [resolves #297] --- docs/framework-ruxit_agent.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/framework-ruxit_agent.md b/docs/framework-ruxit_agent.md index 46c3199e31..beea240d92 100644 --- a/docs/framework-ruxit_agent.md +++ b/docs/framework-ruxit_agent.md @@ -1,6 +1,6 @@ +# Dynatrace Ruxit Agent Framework [Dynatrace Ruxit](http://www.dynatrace.com/en/ruxit/) is your full stack monitoring solution - powered by artificial intelligence. Dynatrace Ruxit allows you insights into all application requests from the users click in the browser down to the database statement and code-level. -# Dynatrace Ruxit Agent Framework The Ruxit Agent Framework causes an application to be automatically configured to work with a bound [Ruxit Service][] instance (Free trials available). @@ -19,7 +19,7 @@ The Ruxit Agent Framework causes an application to be automatically configured t Tags are printed to standard output by the buildpack detect script ## User-Provided Service -Users may optionally provide their own Ruxit service. A user-provided Ruxit service must have a name or tag with `ruxit` in it so that the Ruxit Agent Framework will automatically configure the application to work with the service. +Users must provide their own Ruxit service. A user-provided Ruxit service must have a name or tag with `ruxit` in it so that the Ruxit Agent Framework will automatically configure the application to work with the service. The credential payload of the service may contain the following entries: From c4dc3e461c4fe88d6018c361368ac96cf26dcef8 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 20 May 2016 11:06:23 -0700 Subject: [PATCH 174/812] Update Ruby Versions This change updates the Ruby Versions to 2.2.5 and 2.3.1. --- .ruby-version | 2 +- ci/docker-image/Dockerfile | 4 +-- java-buildpack.iml | 58 +++++++++++++++++++------------------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.ruby-version b/.ruby-version index 530cdd91a2..21bb5e156f 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.2.4 +2.2.5 diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index b589681a51..3a6629f441 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -33,7 +33,7 @@ RUN eval "$(rbenv init -)" \ && rbenv install 1.9.3-p551 RUN eval "$(rbenv init -)" \ -&& rbenv install 2.2.4 +&& rbenv install 2.2.5 RUN eval "$(rbenv init -)" \ -&& rbenv install 2.3.0 +&& rbenv install 2.3.1 diff --git a/java-buildpack.iml b/java-buildpack.iml index ec50298002..5a5e7008ca 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -266,36 +266,36 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 8a15b65bcbd945265e42058f55752c900314d8b2 Mon Sep 17 00:00:00 2001 From: Jonathan Patchell Date: Mon, 16 May 2016 18:17:11 -0400 Subject: [PATCH 175/812] Luna Security Provider, Minimal Install This change updates the Luna Security Provider to support the new Minimal Client Installer. It also updates the code to depend on the 6.+ versions of the client. [#296] --- config/components.yml | 2 +- config/luna_security_provider.yml | 6 +- .../framework/luna_security_provider.rb | 67 ++++++--------- lib/java_buildpack/framework/rpm2cpio.py | 85 ------------------- 4 files changed, 32 insertions(+), 128 deletions(-) delete mode 100755 lib/java_buildpack/framework/rpm2cpio.py diff --git a/config/components.yml b/config/components.yml index 453c574c8e..0bb53ef3ca 100644 --- a/config/components.yml +++ b/config/components.yml @@ -43,7 +43,7 @@ frameworks: # - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::Jmx" - "JavaBuildpack::Framework::JrebelAgent" -# - "JavaBuildpack::Framework::LunaSecurityProvider" + - "JavaBuildpack::Framework::LunaSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration" diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index e326f10783..ff00b92767 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -13,8 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Configuration for the Dynatrace framework +# Configuration for the Luna Security Provider framework --- -version: 5.+ -repository_root: "" +version: 6.+ +repository_root: "http://files.cf-hsm.io/luna-installer" logging_enabled: false diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index f2c39366fa..ad451b0a06 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -28,7 +28,10 @@ class LunaSecurityProvider < JavaBuildpack::Component::VersionedDependencyCompon # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download(@version, @uri) { |file| expand file } + + download_tar + setup_ext_dir + @droplet.copy_resources credentials = @application.services.find_service(FILTER)['credentials'] @@ -63,10 +66,6 @@ def chrystoki @droplet.sandbox + 'Chrystoki.conf' end - def cklog(root) - Dir[root + 'cklog-*.x86_64.rpm'][0] - end - def client_certificate @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem' end @@ -75,49 +74,43 @@ def client_private_key @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-private-key.pem' end - def expand(file) - with_timing "Expanding Luna Client to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do - Dir.mktmpdir do |root| - root = Pathname.new(root) - - FileUtils.mkdir_p root - shell "tar x#{compression_flag(file)}f #{file.path} -C #{root} --strip 3 2>&1" + def ext_dir + @droplet.sandbox + 'ext' + end - install_client root - end - end + def luna_provider_jar + @droplet.sandbox + 'jsp/LunaProvider.jar' end - def ext_dirs - "#{qualify_path(@droplet.java_home.root + 'lib/ext', @droplet.root)}:" \ - "#{qualify_path(@droplet.sandbox + 'usr/safenet/lunaclient/jsp/lib', @droplet.root)}" + def luna_api_so + @droplet.sandbox + 'jsp/64/libLunaAPI.so' end - def install_client(root) - FileUtils.mkdir_p @droplet.sandbox + def lib_cryptoki + @droplet.sandbox + 'libs/64/libCryptoki2.so' + end - Dir.chdir(@droplet.sandbox) do - shell "#{rpm2cpio} < #{libcrpytoki root} | cpio -id ./usr/safenet/lunaclient/lib/libCryptoki2_64.so" - shell "#{rpm2cpio} < #{lunajsp root} | cpio -id ./usr/safenet/lunaclient/jsp/lib/*" + def lib_cklog + sandbox + 'libs/64/libcklog2.so' + end - if logging? - shell "#{rpm2cpio} < #{cklog root} | cpio -id ./usr/safenet/lunaclient/lib/libcklog2.so" - end + def setup_ext_dir + FileUtils.mkdir ext_dir + files = [luna_provider_jar, luna_api_so] + files.each do |file| + FileUtils.ln_s file.relative_path_from(ext_dir), ext_dir, :force => true end end - def libcrpytoki(root) - Dir[root + 'libcryptoki-*.x86_64.rpm'][0] + def ext_dirs + "#{qualify_path(@droplet.java_home.root + 'lib/ext', @droplet.root)}:" \ + "#{qualify_path(ext_dir, @droplet.root)}" end def logging? @configuration['logging_enabled'] end - def lunajsp(root) - Dir[root + 'lunajsp-*.x86_64.rpm'][0] - end - def padded_index(index) index.to_s.rjust(2, '0') end @@ -126,10 +119,6 @@ def relative(path) path.relative_path_from(@droplet.root) end - def rpm2cpio - Pathname.new(File.expand_path('../rpm2cpio.py', __FILE__)) - end - def server_certificates @droplet.sandbox + 'usr/safenet/lunaclient/cert/server/server-certificates.pem' end @@ -191,7 +180,7 @@ def write_lib(f) write_logging(f) else f.write < Date: Fri, 20 May 2016 10:31:43 -0700 Subject: [PATCH 176/812] Luna Security Provider Polishing This change updates the contributed Luna Security Provider changes to simply the code even further. In addition, it updates the test code to account for the changes. [resolves #296] --- .idea/dictionaries/bhale.xml | 1 + .../framework/luna_security_provider.rb | 23 ++++++------- .../luna_security_provider/Chrystoki.conf | 17 ++++------ .../Chrystoki.conf | 28 +++++++--------- .../Chrystoki.conf | 30 ++++++++--------- spec/fixtures/stub-luna-security-provider.tar | Bin 62976 -> 12288 bytes .../framework/luna_security_provider_spec.rb | 31 +++++++----------- 7 files changed, 54 insertions(+), 76 deletions(-) diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 517b1bbd2a..1b7ed1d682 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -67,6 +67,7 @@ pkill postofficehub preformatted + priv progname proto ratpack diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index ad451b0a06..745be485b2 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -28,7 +28,6 @@ class LunaSecurityProvider < JavaBuildpack::Component::VersionedDependencyCompon # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_tar setup_ext_dir @@ -67,11 +66,11 @@ def chrystoki end def client_certificate - @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem' + @droplet.sandbox + 'client-certificate.pem' end def client_private_key - @droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-private-key.pem' + @droplet.sandbox + 'client-private-key.pem' end def ext_dir @@ -91,14 +90,13 @@ def lib_cryptoki end def lib_cklog - sandbox + 'libs/64/libcklog2.so' + @droplet.sandbox + 'libs/64/libcklog2.so' end def setup_ext_dir FileUtils.mkdir ext_dir - files = [luna_provider_jar, luna_api_so] - files.each do |file| - FileUtils.ln_s file.relative_path_from(ext_dir), ext_dir, :force => true + [luna_provider_jar, luna_api_so].each do |file| + FileUtils.ln_s file.relative_path_from(ext_dir), ext_dir, force: true end end @@ -120,7 +118,7 @@ def relative(path) end def server_certificates - @droplet.sandbox + 'usr/safenet/lunaclient/cert/server/server-certificates.pem' + @droplet.sandbox + 'server-certificates.pem' end def write_client(client) @@ -209,11 +207,10 @@ def write_prologue(f) LunaSA Client = { NetClient = 1; - ClientCertFile = #{relative(@droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem')}; - ClientPrivKeyFile = #{relative(@droplet.sandbox + 'usr/safenet/lunaclient/cert/client/client-private-key.pem')}; - HtlDir = #{relative(@droplet.sandbox + 'usr/safenet/lunaclient/htl')}; - ServerCAFile = #{relative(@droplet.sandbox + 'usr/safenet/lunaclient/cert/server/server-certificates.pem')}; - SSLConfigFile = #{relative(@droplet.sandbox + 'usr/safenet/lunaclient/bin/openssl.cnf')}; + ClientCertFile = #{relative(client_certificate)}; + ClientPrivKeyFile = #{relative(client_private_key)}; + HtlDir = #{relative(@droplet.sandbox + 'htl')}; + ServerCAFile = #{relative(server_certificates)}; EOS end diff --git a/resources/luna_security_provider/Chrystoki.conf b/resources/luna_security_provider/Chrystoki.conf index 1d2d5d9327..19439d9956 100644 --- a/resources/luna_security_provider/Chrystoki.conf +++ b/resources/luna_security_provider/Chrystoki.conf @@ -1,16 +1,13 @@ Luna = { - DefaultTimeOut = 500000; - PEDTimeout1 = 100000; - PEDTimeout2 = 100000; - PEDTimeout3 = 10000; + CloningCommandTimeOut = 300000; + CommandTimeOutPedSet = 720000; + DefaultTimeOut = 500000; KeypairGenTimeOut = 2700000; - CloningCommandTimeOut = 300000; -} - -CardReader = { - RemoteCommand = 1; + PEDTimeout1 = 100000; + PEDTimeout2 = 200000; + PEDTimeout3 = 10000; } Misc = { - ToolsDir = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/bin; + PE1746Enabled = 0; } diff --git a/spec/fixtures/framework_luna_security_provider/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider/Chrystoki.conf index cdb2ac905c..fb7ed3e389 100644 --- a/spec/fixtures/framework_luna_security_provider/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider/Chrystoki.conf @@ -1,32 +1,28 @@ Luna = { - DefaultTimeOut = 500000; - PEDTimeout1 = 100000; - PEDTimeout2 = 100000; - PEDTimeout3 = 10000; + CloningCommandTimeOut = 300000; + CommandTimeOutPedSet = 720000; + DefaultTimeOut = 500000; KeypairGenTimeOut = 2700000; - CloningCommandTimeOut = 300000; -} - -CardReader = { - RemoteCommand = 1; + PEDTimeout1 = 100000; + PEDTimeout2 = 200000; + PEDTimeout3 = 10000; } Misc = { - ToolsDir = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/bin; + PE1746Enabled = 0; } Chrystoki2 = { - LibUNIX64 = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/lib/libCryptoki2_64.so; + LibUNIX64 = .java-buildpack/luna_security_provider/libs/64/libCryptoki2.so; } LunaSA Client = { NetClient = 1; - ClientCertFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/client/client-certificate.pem; - ClientPrivKeyFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/client/client-private-key.pem; - HtlDir = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/htl; - ServerCAFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/server/server-certificates.pem; - SSLConfigFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/bin/openssl.cnf; + ClientCertFile = .java-buildpack/luna_security_provider/client-certificate.pem; + ClientPrivKeyFile = .java-buildpack/luna_security_provider/client-private-key.pem; + HtlDir = .java-buildpack/luna_security_provider/htl; + ServerCAFile = .java-buildpack/luna_security_provider/server-certificates.pem; ServerName00 = test-server-1; ServerPort00 = 1792; diff --git a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf index 9d4c34d1f9..0c149226c3 100644 --- a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf @@ -1,27 +1,24 @@ Luna = { - DefaultTimeOut = 500000; - PEDTimeout1 = 100000; - PEDTimeout2 = 100000; - PEDTimeout3 = 10000; + CloningCommandTimeOut = 300000; + CommandTimeOutPedSet = 720000; + DefaultTimeOut = 500000; KeypairGenTimeOut = 2700000; - CloningCommandTimeOut = 300000; -} - -CardReader = { - RemoteCommand = 1; + PEDTimeout1 = 100000; + PEDTimeout2 = 200000; + PEDTimeout3 = 10000; } Misc = { - ToolsDir = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/bin; + PE1746Enabled = 0; } Chrystoki2 = { - LibUNIX64 = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/lib/libcklog2.so; + LibUNIX64 = .java-buildpack/luna_security_provider/libs/64/libcklog2.so; } CkLog2 = { Enabled = 1; - LibUNIX64 = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/lib/libCryptoki2_64.so; + LibUNIX64 = .java-buildpack/luna_security_provider/libs/64/libCryptoki2.so; LoggingMask = ALL_FUNC; LogToStreams = 1; NewFormat = 1; @@ -30,11 +27,10 @@ CkLog2 = { LunaSA Client = { NetClient = 1; - ClientCertFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/client/client-certificate.pem; - ClientPrivKeyFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/client/client-private-key.pem; - HtlDir = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/htl; - ServerCAFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/cert/server/server-certificates.pem; - SSLConfigFile = .java-buildpack/luna_security_provider/usr/safenet/lunaclient/bin/openssl.cnf; + ClientCertFile = .java-buildpack/luna_security_provider/client-certificate.pem; + ClientPrivKeyFile = .java-buildpack/luna_security_provider/client-private-key.pem; + HtlDir = .java-buildpack/luna_security_provider/htl; + ServerCAFile = .java-buildpack/luna_security_provider/server-certificates.pem; ServerName00 = test-server-1; ServerPort00 = 1792; diff --git a/spec/fixtures/stub-luna-security-provider.tar b/spec/fixtures/stub-luna-security-provider.tar index 19e12219aca5a1f32e716240dca7029390eb1f80..440fd9064c66739fef34128bab10089dec014130 100644 GIT binary patch literal 12288 zcmeI2OK#&Z42E+QU!WQ4y)L>cFpFLxO_SEC8wYkeKyP14%4%w7C{T!JK?8wdhw?)o zDg6}PeI7U4uH7BacOUKX&ad^aRqYJ`f^*F(?tR{aw&@s8rL9pqC})-Opc+utDZ6T1 z?FX5<-sgDU4ESizZ<}s6WpFu%X8Zk>|1a+mUlOT|>C;XS>Zz}4*0{+^XsQ;V~M))tu-`jdaKoNhXGyfp`7v_)i!1lfCU-f$I zS&u^HAG{6VLIWCq)>8{@&pFAM*E7|K-CaTw$Jn z{tSRE{_q(J^q&tQt^b0>`mc=t1b|GFdHz`fUc7)+0iecz(*Kb7dnNNflPsHEKjx8ZAyrJr>?vU-?Js>?G JJ@Ahn_y!_&o#Frh literal 62976 zcmeHQ349Y({+~&Uq^U|k5ENL$B9}cflRJ3Oq)D%&2TgiKr6ie2lQvg#G;I;Bh_0@# z_r{Q*IiNZT5pc^SiCP*{=YZ#rlbYZU@I1xm(S!k-*?Tt-#foE z@69V#7PrO|Nl#HQ8Fm-NS#L5HNc0p%W09@^!^Vh_Fcd}UwOR#%q>h)AO2c8Wq9~0{ zub@>rHLamFU=$RsSJ7HRL5;-4hl(Q^Pq<@nYaYKl$Y$^i-h93c?p#VJAyJA9K1Y|+ zm?Os$5`w69dlj_~MY94MWJlz|p&|%!3`oGFKD%2tIi2;qPcFpOaDM%ukR)Jie}p#@ zDt1SsLAKcK4HhTZ?gTi_mBcQ6=96$Zk77Rocr6#4=|wiUxdCJPNi2KlRlW_|DNzZ&JgR;$<3S{ITwo!0)N5U8E+8{}7L|G|F0wEqWh13yUdgJH({KO(iCK=nRD{a0yV z1UR_HlA)nqL-bNOkdz+^e|s><9UZ$FG+IPv0vu4cp=s#$q~cLe zFyi6t#XnI4q6S0_h#C+zAZlRrX#kDK!ASFYDgKKZ5H%obpkD*1eNe!GWC@miyyTh= z_~R%5$Xu}I44iY12tX>31;`RC`*;a9U`ReFNIocuDF(?02YUtfSAu09FZtjE$z2)Z z!B-|RLm}}43R1y&C&&_BivOYpL=Eh&0mR+M5J4h9go)$;{{Dj}8Vtk}6!jV@$;lma z$XIEf49wv&`S`<6b@(GG2fQOm#?9{7$sB?=haP-h=T7*Ab7v$H>_2yV8Ut*qRX(va z5>B`SVK$Z)^pvJRn2Ds!kz|;OpW@)-YYH$4f2({_U5xF5pmpvr+Zc!kJb@s*vCIP_ z&1;n(y<~|B-X0bzvjGLZK)T?N}{2fW6L@_}pG2D!$&>i8!ilFI~5zP?M7 z`T6;Wms+e7%gS5ja(LfW&j#IzKo@IqC)jwad|Vt9TnHwm6tQ!wZV z^s@0LZzPxug*o5eSR@#%i^KzoKqTDKjNYdqKPaLBPR*`(B$g=U0yYOAe%{vvq}$pk z3LI}_V{wq6+S|uXnLcB70i~V4V55Begd-+S%FlN}wuBP_Ux1A@q)^_pxZ_?n%ml)1 zO>jwcKAnjxn`aOZK}`h=+`N###V7olt0-SI?ilnw8?E3;JEf?P}t!!k4Z z{3VE)C3E@HG#iSyk)!TwIzbU;qLElcM2Q~aeBw%Y0lJo0N8C?5K>VF}j(CN56CSF6 zN_;_lO?*RqOOm97%q7Q=6UeFLG;%sQk5rLrQcLQ{<4Fr?CCkYQvYKopo5&W@MJ^@- zWIGuoLu8UXojikFMxI4pKwd#!NnTB^Aa5ntkoS`Jk$)kdB>zEfBH!ijOCpr;3Lz1^ zB;N;_UX7TKeqAW#2IzCtMHgUf#d6i&9AD{b(+Eb$WY9#>4iBYq?gA@j*8J(Yw)%E?a*xQd5{l-a(?G`gzpcSQIN3dHoeZ`9W4HBR zDoRD`#reO(R(v)QWHJ9=T>pjFf*oY*zqr~z0;|A=s{i0VaQzoNvev-*PjUTMHWhey zeloZJv1lkhy!cV*q4Gby{nzPfwEm0IsKxew_?pim2C@Bz1;PjK@~}+xAJzU5X#R(+ z|LN^NSN~}}2(kUoqV^8k%aHj$0*inle>1HALv8)8^}kw;9@>9eM~UtKu=6&n2(oDZ z#r3~gY4U*dG<5wR{vzPa^`9QF{ukGOwVo2kfBUIG;q||AxEy*^k0db*{q1g$J34kV z{6l-*8Xn|xaqQ+vv=B8QYCzP0r~y#}q6S8l2Kbln;`-lFl_}!Qh#D9r8bIxX0uCfg zu3|FwEMf|0f&ZLy|URYYrwyA8Tlou)V*WxZMI zEc5$6;r&0q{{xyRK&jyMAI$%tvW$ON-VXBbzZ3iX{(op~i{JkqT1TVB$B^}Z*tLJC z?|)O2N{hb#J)r(;#P|REr-V3?p^!V)Ghbm1MH4-W`nqaa4Scg{zJkkl8U6y)dwhsU0`hocJ<&v@Bk|Mk1p|LC~-uYsL_#PRi_xm|HEGZm|g#$zW*l; z`^Ad=|48Tc9^>2R{$JexbB}sFKrOSV|HEDYn7RJL#~yau|C83L#qa;@uM&mV|DkC* z!gL*O9^f9XKjiv9d7Jwzm0i5d_!AZkF=fT#gc1HZfm_zAe;`oCX3 zC&W7tH8A=#fZ7KI97vX6*~d$+>43ihQ~$w<=K;J_U|fP_A1}F};7^?PkMtoLQ3JoE z1`v0b5IRD00PlM?!aIL*>PX-7jI$WH-&rx52G83c;p|hC(C+`1sFz^4R(+qbHn4#)FxC`t5h5D~X-~SNz|H`%!|8##txBrm; z!<+&R`J3(jFEH^N?f;@u(c=2ApPs4v5;BYSU)=v?Ule*^`OU8W4{r*1=K4Qi{}){U zX}w-2uK(CiB}v@>Wj`reyo{&;Q3Ij|L=A`<7-bsZU%-g-zeicNh_@qZU{q)TwGRq7 zkSxKnkC$B20e=Ht`+^hlEAIb-6d@W>1EX96c>b5T|H~-PC-L?~4g8!M7;^p>>g^Zf zJ3!}saDYUo=x@Lv005f%CGP)%lp`8Z1EK~*4U94kWcB`U&wD_?=OMF8%pTtV(JHEc z{+Cv(R`<{U&`@apms+nHZQp-#Goe5@LwX^RV1z^|GWZ--PM_TI=^J?PKN9yfW^g1I zuHMRx4ZwaZLFAyZz)Ac$83YLr2*^Wu4F3dK0LNi)atMEph7>tl0mFuHq!W1n{4q#~ zi);o7;dB0r-TlaY!OopKvHNKNuRV{Pn@f-qV!{|nqi^aVV{(W&e;_2egal%c<;i8& ztj&M@nB&z;R!fPQ&!4`!dF81=+uGMRPMmr48F_zqdS)#kU-leYFy|%31;MqJ+#BbO z{rCKe8}592tn<$gPI{sFp?@AR=kupm$p7_$)6lr)%nF93j zhht2+??1Wro5)+Tj_&5SUM4Hf_A_Tqy8nsxy7o^fK0MsoD#tL9B>c~L7}GkwFX z!_Ek`^j)kee(v){>gc)pFXAV){wsCgr8ij~zdJOkLbCng?aAU(^mArQHyK`gwsreo zcTD)(l>29WJM+;u*x>DZ&$5qKhV^w;_qtj|t zUbWt*(P?!)y@A%bDG!a*>;3$dcS7M$wm0TEKYMBNq8O~eA}4|am$#4wE8(1b_ybZj zqfi5B^-=?M=xVsd1#qA`dM-$mcMKe8{EiINI}&|-6=5{S7wRRdr`s?_5@A#yk^6rz z{t9DMZ}Y(ETZ}*9u|$aPQ@~KqC8#|>;ZZygp9I|t!k=Mx1;$^4MDE98jN*m(CD4X& z{{M&FQMyq0A2BZDaV}hoyIvi}5ElVWp#--xxeynJ8?ie|Ke|8E?m&FGXpJ1`Lvjkn z=)MtNiZN=(kpDi6$ALud%P~gjLijw4QT;*bxe((?AW`^RF`f((`G>m3U4Je}r`Fy4f5B}f$Cn;4^XA^-1S+yWB0e}FMcCvxA8@u}GTONha<24vBN4S(ILdI+@udGqj zmDefi8qD^}QiaXhqA=TQOKqIMoZkDO0-rn*UYlq_67>rVXv5;CzFL1T5HT@ zu26ZZ#awDCZL_EX%tEKXpjTs0ws*O@e9B~7PblGP?=01p7pSR_xrJgwR&PhDH({eI z9PN>|8fB0P%2LV{t?jnbw(5knIccqHtn4i4X{>h{%G*uBSZB)IY4cV$7^p}~%-3vG zS#5O*y3=X1H^-fcW^2k&8xNJ*lZ`rAkT&-?j0Q(TZ=j>i5lnV;S9+~&!MM@pPU+(= zwmj5mPZb1MGi5V1GFN&n+kEBi9wk#*(AHbe z>SSFSSJEEVX;TJ=L*p;^2g|#a>R=+Is?+ET81q6+xT+&z2>C1yXEJ3>m@Q0lAyXA# zC~st;w#8k_boiYnv(+p!nXD(uPBbm-)ylX$vesBKWFWzfg$ZsuEP~b${kvJEouPq- zzb6`wBqDC6I2iG|QBfucexod64?AQLj60Ts;U&MfBIgYcx=l(P&`3K7&T3NA-v^u}CCAaDRga?D3el7?0MWZ{E2p39!q`pc{pqy);Ix zT1D%0#A&T2*+t>|AHmT}g)Ja4Cek%Sj!q_65 zb|F^iUzk9Q^(G>*9)d-?lJ&d5iNbg6bM&&Zf>q}!p7o5|{svf)b1y!DSi03uK%GKU z#<_lM=gu7);9P#p`OqYQk>sc;J^a>IsBP6MTa}KGV zUu?Tv>fN^Osv{?Fn>^>1n>XKl<<>2iZ=N-K3va^D#kJR7ciHvfRZZ9aV=>Wn z71`O>oZL!$dfCN_^4eowRamXoLlgw@`?4z}6QKb)AWT;LFKsWF-F5-Vf&~IE8a)4d zApg^A`}v=iM*DwiY5i!M|1I*rY|8T}=YRIW{O|bcys>l_F@M_*DbcjSurqkhU!LD| z_@%Eb|EKrOIq&>-N8_5~`#SrUHotE&ExWpWw&vbq?|&xQKK}5qb>D_AjeT_9*TH3f zeQ&1X@K27je|^-N)qQWgdisn@6gPb4S~6AjvA%BOQs*--<(Ax3CLzbJ{%oA@tG1`L z?|gCkcay#;{QOJ6GfQ5d+I{=-TmM{t-n_p&Hu?K2);;y?tKswB zBP~B3TJ`R`wg>+A;iN~eS#e*&_RN@X?}}Wvy<+9zGiLnw<=lmnR*gw+7$Z4t{O>M$ zWV%WB>i4gADA(LvZB;+ES{c8A-BEtdWt-^6mEUa}YaJVDnPQ&$ySHC^`Roa6p7lMo z#kKCJ^Xq51*Qigr&$I9ol}h7Pc{H>~ZS=A_+N)Q&eQsK3R2h9N?PVyMfoiNas-YZ= zJ$pgH3%4vhqF9OE*KpTiiXI~UxyVqAgo#~2Iz zZ#%|F56J(Q7z_Ll=@sb%=>^<#;NURke>so_4kJCmdCpXf1^#Eim;nj*n{xuj0{=5% z?8ELT9q4*NjM04~oB)ZgFXWHF{}y9+f&ZcFr1QUS?2aS~e;URD|LX$`dC|}RF2?Qx z|GOOHdqAS_S7R*jziScxdH5fdLi{hTYw2t;mqqlARX($?wANRdum}7d2_{q<>JBtJ z%mrE&_TH@yM>--(Ki%0)2ZD`pPtqv!QuR%B)s6t&tPIyyE0gY~u)mfKbai<=VOv+y zWK7x(=8z+0=x8x})r{ZWS(#F`#X6~&NzFtJo~p`NWm6SZBkQfRs5-mbEnP7iMeE%* zcaPOjZ82AN(RGzIJ+=y_O4Aef>DmJoO^#qg7j28x+Z(IeYpIGvsM)M!qv{Hi-s&~U z?CPYg(-16h_A-^WUQeyZP#=lv_4?-ShM23MQ>E<)`^()Xdq+TBPFFRByQ}>1Xws1E zRngT=rDd^%D{j?!q8gcz*7`#lRU%^c1=>33YMY0$EM$}cFQs+$bhm`nzB;$P%UWA* z(tF)0sv}4R^)&%sb(=Qs>glOV^(f88H2&vsS6Z{;e`#ak%q)=OZuUX+3W~~4=7AOa z&I8kKcGtkYpA8}|nC62^&fXcJO09!?N1X76H~ZFc34!{)2TnL>tHu#yh8cO`oJ(e0 zyY=21I;MWpdZX*@a?}>@6EC!D?3MRZ6)No@Uii%8l2bWmcxYQDV)*eX&X&4MufHxZ zG2*)s=;4M9KoGCz38EtJNoii}%P%_*t9LqcT`v&C$JO6oFb$ftQDCy;e|y;hG7Ij9 zk~k#))9!lzr`4nNzZx|yzW>`VrQ_gw|98e<{`cM3ng&hsuuWIbloI3CNoSvb{K|E! zntk$DA1ppxdglHA%Uk~Z2|0GN_r6CSH;-GdR(2NNHStH&rdK|HZ3}C;sO*Z8#O1-t zoipw@>A}R7!apAS#rgB@d*f{Bk7sR(eDwYM%l>xf*~R&l>!0wy{?(PYTL1e{`42k{ z_nq<9V~-zs+fD!Yfn6=Vd%gO3tAEaV_wo6&E?srkf}2hxR;-%2;W+7>D(`LYJrJiK zUR1X;-!RLz?6mV9X?mgLjfelQPdV1I>~D`Q`Sha2vzNG6c$#K> zatrbHtM#qPbLQ4v_vX8YYEPei1|+!U z6ksgyKMG?XcGqGY#8{7U0wi3Yd%uUSFYv!Q>@M&>l%MJR&yU@^ad;Fj3NP@#C}25Y z;r(A9b{F{Ha*Xc*iLQSx#sdGl0O6m9|EUd#|FsvG+p3e4*`H{kD#H%r!icx0(#JMc zbm=WYO>Kvp?)72rbi;s;Z5iiiEGl(2xkb+S#Zp+}v)i zH?Zb#K%cDlbyt--jb6Pn#8hP}gMt}T-6O4$tc<(6KnCsd#hE;N?a`Kw&1rU>gO?^d3HD zVH@4v*i>JY@H%5X8ePcWRFLWoIoU{CZDmt+Pg9twPvd`9pRFr9{>P7nv*3Pbj3D>x z{R!M}@SuGl?@LQY2F_g)ngw*^#_^VI3MB=-1fYCrFz0fzWekdFeBf4-*D`s ze&v+D4VOQ>w9~iT4fnNge9ul(wN;u2sKI>igz-GzyF7PqZvwB_+BRwO)-BBJZIiFM zeD=1R+0Cm|#F^x#&>@eLo|kXPS^tK4*|Zavo^sa2Ns~-nIm8Rg?!IseG&rIWH6Ut0 K)WE3H!2bj7fmwtA diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index a01e5a3e82..7600072b62 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -77,9 +77,10 @@ component.compile - expect(sandbox + 'usr/safenet/lunaclient/lib/libCryptoki2_64.so').to exist - expect(sandbox + 'usr/safenet/lunaclient/jsp/lib/stub.file').to exist - expect(sandbox + 'usr/safenet/lunaclient/lib/libcklog2.so').not_to exist + expect(sandbox + 'libs/64/libCryptoki2.so').to exist + expect(sandbox + 'libs/64/libcklog2.so').to exist + expect(sandbox + 'jsp/LunaProvider.jar').to exist + expect(sandbox + 'jsp/64/libLunaAPI.so').to exist end it 'write certificate files', @@ -87,15 +88,15 @@ component.compile - expect(sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem').to exist - expect(sandbox + 'usr/safenet/lunaclient/cert/client/client-private-key.pem').to exist - expect(sandbox + 'usr/safenet/lunaclient/cert/server/server-certificates.pem').to exist + expect(sandbox + 'client-certificate.pem').to exist + expect(sandbox + 'client-private-key.pem').to exist + expect(sandbox + 'server-certificates.pem').to exist - check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/client/client-certificate.pem', + check_file_contents(sandbox + 'client-certificate.pem', 'spec/fixtures/framework_luna_security_provider/client-certificate.pem') - check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/client/client-private-key.pem', + check_file_contents(sandbox + 'client-private-key.pem', 'spec/fixtures/framework_luna_security_provider/client-private-key.pem') - check_file_contents(sandbox + 'usr/safenet/lunaclient/cert/server/server-certificates.pem', + check_file_contents(sandbox + 'server-certificates.pem', 'spec/fixtures/framework_luna_security_provider/server-certificates.pem') end @@ -118,22 +119,12 @@ expect(java_opts).to include('-Djava.security.properties=$PWD/.java-buildpack/' \ 'luna_security_provider/java.security') expect(java_opts).to include('-Djava.ext.dirs=$PWD/.test-java-home/lib/ext:$PWD/.java-buildpack/' \ - 'luna_security_provider/usr/safenet/lunaclient/jsp/lib') + 'luna_security_provider/ext') end context do let(:configuration) { { 'logging_enabled' => true } } - it 'unpacks the luna tar', - cache_fixture: 'stub-luna-security-provider.tar' do - - component.compile - - expect(sandbox + 'usr/safenet/lunaclient/lib/libCryptoki2_64.so').to exist - expect(sandbox + 'usr/safenet/lunaclient/jsp/lib/stub.file').to exist - expect(sandbox + 'usr/safenet/lunaclient/lib/libcklog2.so').to exist - end - it 'writes configuration', cache_fixture: 'stub-luna-security-provider.tar' do From 29c79f2eabddce19b23960a81e6d8f51975b8d93 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 3 Jun 2016 12:14:03 -0700 Subject: [PATCH 177/812] Prospective Memory Heuristic Changes This change updates the memory heuristics to take into account, most people are running within containers that have around 250 threads at maxiumum. In addition, it enforces the VM-minimum stack size, and allows the native and stack regions to breath a little more. --- config/open_jdk_jre.yml | 14 +++++++------- config/oracle_jre.yml | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 63e43d9f30..b70efe388c 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -22,19 +22,19 @@ jre: memory_calculator: version: 2.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" - stack_threads: + stack_threads: 300 memory_sizes: - heap: + heap: metaspace: 64m.. - native: + native: permgen: 64m.. - stack: + stack: 228k.. memory_heuristics: - heap: 75 + heap: 65 metaspace: 10 - native: 10 + native: 15 permgen: 10 - stack: 5 + stack: 10 memory_initials: heap: 100% metaspace: 100% diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index 9c481b77fb..6d82222470 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -24,20 +24,20 @@ jre: repository_root: "" memory_calculator: version: 2.+ - repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' - stack_threads: + repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + stack_threads: 300 memory_sizes: heap: metaspace: 64m.. native: permgen: 64m.. - stack: + stack: 228k.. memory_heuristics: - heap: 75 + heap: 65 metaspace: 10 - native: 10 + native: 15 permgen: 10 - stack: 5 + stack: 10 memory_initials: heap: 100% metaspace: 100% From 91e11eb4ec4904b1e39cc47dce2307a929602c1c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Sat, 11 Jun 2016 07:44:26 -0700 Subject: [PATCH 178/812] Polishing This change updates the configuration so that the automatic pinning results in a net change of only version numbers. --- config/luna_security_provider.yml | 2 +- config/open_jdk_jre.yml | 4 ++-- config/oracle_jre.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index ff00b92767..415f970cf4 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -16,5 +16,5 @@ # Configuration for the Luna Security Provider framework --- version: 6.+ -repository_root: "http://files.cf-hsm.io/luna-installer" +repository_root: http://files.cf-hsm.io/luna-installer logging_enabled: false diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index b70efe388c..f7627ad731 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -24,9 +24,9 @@ memory_calculator: repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" stack_threads: 300 memory_sizes: - heap: + heap: metaspace: 64m.. - native: + native: permgen: 64m.. stack: 228k.. memory_heuristics: diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index 6d82222470..d801e272e3 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -27,9 +27,9 @@ memory_calculator: repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" stack_threads: 300 memory_sizes: - heap: + heap: metaspace: 64m.. - native: + native: permgen: 64m.. stack: 228k.. memory_heuristics: From 7a37ff3ef79ac65fc54f87256ad73a439b1d92fa Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 14 Jun 2016 13:57:11 -0700 Subject: [PATCH 179/812] Update Repository Location This change updates the repository location for buildpack dependencies. --- config/repository.yml | 2 +- docs/buildpack-modes.md | 6 +++--- docs/debugging-the-buildpack.md | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config/repository.yml b/config/repository.yml index 22f04e9b6d..62ad872adf 100644 --- a/config/repository.yml +++ b/config/repository.yml @@ -15,4 +15,4 @@ # Repository configuration --- -default_repository_root: https://download.run.pivotal.io +default_repository_root: https://java-buildpack.cloudfoundry.org diff --git a/docs/buildpack-modes.md b/docs/buildpack-modes.md index 73a0b858a4..c74621dc40 100644 --- a/docs/buildpack-modes.md +++ b/docs/buildpack-modes.md @@ -1,8 +1,8 @@ # Buildpack Modes The Java Buildpack has three execution modes as described in the blog post, ['Packaged and Offline Buildpacks'][l]. -* **Easy Mode:** Uses the repository at `https://download.run.pivotal.io`. This does not require any cloning or downloading unless you want to modify the Cloud Foundry provided buildpack. This is the default, and what we recommend to anyone who asks. -* **Expert Mode:** Refers to a repository hosted at a different location, possibly on an internal network. The [structure of the repository][r] is defined as an HTTP-accessible collection of files. The repository root must contain an `index.yml` file that is a mapping of concrete versions to absolute URIs. This repository can be created manually or [creating a replica](#replicating-the-repository-optional) for the repository at `https://download.run.pivotal.io`. This is what we would recommend to any customer that didn’t want to access the Internet. It’s easy to keep applications secure and up-to-date, but requires the expertise to run a web-server and keep it up to date. +* **Easy Mode:** Uses the repository at `https://java-buildpack.cloudfoundry.org`. This does not require any cloning or downloading unless you want to modify the Cloud Foundry provided buildpack. This is the default, and what we recommend to anyone who asks. +* **Expert Mode:** Refers to a repository hosted at a different location, possibly on an internal network. The [structure of the repository][r] is defined as an HTTP-accessible collection of files. The repository root must contain an `index.yml` file that is a mapping of concrete versions to absolute URIs. This repository can be created manually or [creating a replica](#replicating-the-repository-optional) for the repository at `https://java-buildpack.cloudfoundry.org`. This is what we would recommend to any customer that didn’t want to access the Internet. It’s easy to keep applications secure and up-to-date, but requires the expertise to run a web-server and keep it up to date. * **Offline Mode:** Uses only the packaged internal cache. This is what we recommend if you wanted a single, self-contained artifact. The downside is having to package and keep all your dependencies up to date. @@ -29,7 +29,7 @@ default_repository_root: https:// Once the buildpack has been modified, it needs to be packaged and uploaded to the Cloud Foundry instance. In order to package the modified buildpack, refer to [Building Packages][p]. To add the buildpack to an instance of Cloud Foundry, use the `cf create-buildpack java-buildpack java-buildpack-v.zip` command. For more details refer to the [Cloud Foundry buildpack documentation][b]. ### Replicating the Repository _(Optional)_ -The easiest way to create a fully populated internal repository is to replicate the one found at `https://download.run.pivotal.io`. The [Java Buildpack Dependency Builder][d] contains a `replicate` script that automates this process. To use the script, issue the following commands from the root directory of a clone of this repository: +The easiest way to create a fully populated internal repository is to replicate the one found at `https://java-buildpack.cloudfoundry.org`. The [Java Buildpack Dependency Builder][d] contains a `replicate` script that automates this process. To use the script, issue the following commands from the root directory of a clone of this repository: ```bash $ bundle install diff --git a/docs/debugging-the-buildpack.md b/docs/debugging-the-buildpack.md index 98c9304edf..c5ff96e812 100644 --- a/docs/debugging-the-buildpack.md +++ b/docs/debugging-the-buildpack.md @@ -49,18 +49,18 @@ In either case, the output will look like the following: 2014-04-25T08:06:06.12+0000 [Buildpack] DEBUG Instantiating JavaBuildpack::Framework::SpringAutoReconfiguration 2014-04-25T08:06:06.15+0000 [Buildpack] DEBUG Successfully required JavaBuildpack::Framework::SpringAutoReconfiguration 2014-04-25T08:06:06.15+0000 [ConfigurationUtils] DEBUG Configuration from /tmp/buildpacks/java-buildpack/config/spring_auto_reconfiguration.yml: {"version"=>"0.+", "repository_root"=>"{default.repository.root}/auto-reconfiguration"} -2014-04-25T08:06:06.15+0000 [ConfigurationUtils] DEBUG Configuration from /tmp/buildpacks/java-buildpack/config/repository.yml: {"default_repository_root"=>"http://download.run.pivotal.io"} -2014-04-25T08:06:06.21+0000 [RepositoryIndex] DEBUG {default.repository.root}/auto-reconfiguration expanded to http://download.run.pivotal.io/auto-reconfiguration +2014-04-25T08:06:06.15+0000 [ConfigurationUtils] DEBUG Configuration from /tmp/buildpacks/java-buildpack/config/repository.yml: {"default_repository_root"=>"https://java-buildpack.cloudfoundry.org"} +2014-04-25T08:06:06.21+0000 [RepositoryIndex] DEBUG {default.repository.root}/auto-reconfiguration expanded to https://java-buildpack.cloudfoundry.org/auto-reconfiguration 2014-04-25T08:06:06.21+0000 [ConfigurationUtils] DEBUG Configuration from /tmp/buildpacks/java-buildpack/config/cache.yml: {"remote_downloads"=>"enabled"} 2014-04-25T08:06:06.22+0000 [DownloadCache] DEBUG Proxy: , , , -2014-04-25T08:06:06.24+0000 [DownloadCache] DEBUG HTTP: download.run.pivotal.io, 80, {:read_timeout=>10, :connect_timeout=>10, :open_timeout=>10, :use_ssl=>false} +2014-04-25T08:06:06.24+0000 [DownloadCache] DEBUG HTTP: java-buildpack.cloudfoundry.org, 80, {:read_timeout=>10, :connect_timeout=>10, :open_timeout=>10, :use_ssl=>false} 2014-04-25T08:06:06.24+0000 [DownloadCache] DEBUG Request: /auto-reconfiguration/index.yml, {"accept"=>["*/*"], "user-agent"=>["Ruby"]} 2014-04-25T08:06:06.24+0000 [DownloadCache] DEBUG Status: 200 2014-04-25T08:06:06.24+0000 [DownloadCache] DEBUG Persisting etag: "d093ebc9c94d3050c28898585611701c" 2014-04-25T08:06:06.25+0000 [DownloadCache] DEBUG Persisting last-modified: Thu, 24 Apr 2014 10:47:19 GMT -2014-04-25T08:06:06.25+0000 [DownloadCache] DEBUG Persisting content to /tmp/http:%2F%2Fdownload.run.pivotal.io%2Fauto-reconfiguration%2Findex.yml.cached +2014-04-25T08:06:06.25+0000 [DownloadCache] DEBUG Persisting content to /tmp/http:%2F%2Fjava-buildpack.cloudfoundry.org%2Fauto-reconfiguration%2Findex.yml.cached 2014-04-25T08:06:06.25+0000 [DownloadCache] DEBUG Validated content size 1174 is 1174 -2014-04-25T08:06:06.25+0000 [RepositoryIndex] DEBUG {"0.6.8"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.6.8.jar", "0.7.0"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.7.0.jar", "0.7.1"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.7.1.jar", "0.7.2"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.7.2.jar", "0.8.0"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.0.jar", "0.8.1"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.1.jar", "0.8.2"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.2.jar", "0.8.3"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.3.jar", "0.8.4"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.4.jar", "0.8.5"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.5.jar", "0.8.6"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.6.jar", "0.8.7"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.7.jar", "0.8.8"=>"http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-0.8.8.jar"} +2014-04-25T08:06:06.25+0000 [RepositoryIndex] DEBUG {"0.6.8"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.6.8.jar", "0.7.0"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.7.0.jar", "0.7.1"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.7.1.jar", "0.7.2"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.7.2.jar", "0.8.0"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.0.jar", "0.8.1"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.1.jar", "0.8.2"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.2.jar", "0.8.3"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.3.jar", "0.8.4"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.4.jar", "0.8.5"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.5.jar", "0.8.6"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.6.jar", "0.8.7"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.7.jar", "0.8.8"=>"https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-0.8.8.jar"} ... @@ -104,12 +104,12 @@ app-dynamics-agent=3.8.4 java-buildpack=0fab02b-https://github.com/cloudfoundry/ $ $BUILDPACK_ROOT/bin/compile . $TMPDIR -----> Java Buildpack Version: 0fab02b | https://github.com/cloudfoundry/java-buildpack.git#0fab02b ------> Downloading Open Jdk JRE 1.7.0_60 from http://download.run.pivotal.io/openjdk/mountainlion/x86_64/openjdk-1.7.0_60.tar.gz (found in cache) +-----> Downloading Open Jdk JRE 1.7.0_60 from https://java-buildpack.cloudfoundry.org/openjdk/mountainlion/x86_64/openjdk-1.7.0_60.tar.gz (found in cache) Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (0.4s) ------> Downloading App Dynamics Agent 3.8.4 from http://download.run.pivotal.io/app-dynamics/app-dynamics-3.8.4.zip (found in cache) +-----> Downloading App Dynamics Agent 3.8.4 from https://java-buildpack.cloudfoundry.org/app-dynamics/app-dynamics-3.8.4.zip (found in cache) Expanding App Dynamics Agent to .java-buildpack/app_dynamics_agent (0.1s) ------> Downloading Play Framework Auto Reconfiguration 1.4.0_RELEASE from http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-1.4.0_RELEASE.jar (found in cache) ------> Downloading Spring Auto Reconfiguration 1.4.0_RELEASE from http://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-1.4.0_RELEASE.jar (found in cache) +-----> Downloading Play Framework Auto Reconfiguration 1.4.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-1.4.0_RELEASE.jar (found in cache) +-----> Downloading Spring Auto Reconfiguration 1.4.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-1.4.0_RELEASE.jar (found in cache) $ $BUILDPACK_ROOT/bin/release . | ruby -e "require \"yaml\"; puts YAML.load(STDIN.read)[\"default_process_types\"][\"web\"]" PATH=$PWD/.java-buildpack/open_jdk_jre/bin:$PATH JAVA_HOME=$PWD/.java-buildpack/open_jdk_jre $PWD/play-application-1.0.0.BUILD-SNAPSHOT/bin/play-application -J-Djava.io.tmpdir=$TMPDIR -J-XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh -J-XX:MaxPermSize=64M -J-XX:PermSize=64M -J-javaagent:$PWD/.java-buildpack/app_dynamics_agent/javaagent.jar -J-Dappdynamics.agent.applicationName='' -J-Dappdynamics.agent.tierName='Cloud Foundry' -J-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : '.*instance_id[": ]*"\([a-z0-9]\+\)".*') -J-Dappdynamics.agent.accountAccessKey=[REDACTED] -J-Dappdynamics.agent.accountName=[REDACTED] -J-Dappdynamics.controller.hostName=[REDACTED] -J-Dappdynamics.controller.port=443 -J-Dappdynamics.controller.ssl.enabled=true -J-Dhttp.port=$PORT From d9fce0821d3e7891a2b189b60b21874a74863b91 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 7 Jul 2016 13:12:32 +0100 Subject: [PATCH 180/812] Documentation update This change fixes a broken link [resolves #302] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af73808742..594d11d40f 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,6 @@ This buildpack is released under version 2.0 of the [Apache License][]. [Play Framework]: http://www.playframework.com [pull request]: https://help.github.com/articles/using-pull-requests [Pull requests]: http://help.github.com/send-pull-requests -[Running Cloud Foundry locally]: http://docs.cloudfoundry.org/deploying/run-local.html +[Running Cloud Foundry locally]: http://docs.cloudfoundry.org/deploying/boshlite/index.html [Spring Boot]: http://projects.spring.io/spring-boot/ [Wikipedia]: https://en.wikipedia.org/wiki/YAML#Basic_components_of_YAML From 98bcf424e058ee9f674acb91eb59c0bbfd042688 Mon Sep 17 00:00:00 2001 From: Violeta Georgieva Date: Fri, 22 Jul 2016 13:23:09 +0300 Subject: [PATCH 181/812] TomcatLoggingSupport declares java.endorsed.dirs Tomcat 8.5.x does not declare java.endorsed.dirs by default. TomcatLoggingSupport declares java.endorsed.dirs in order to ensure the classes will be available. [resolves #312] --- lib/java_buildpack/container/tomcat/tomcat_logging_support.rb | 2 ++ .../container/tomcat/tomcat_logging_support_spec.rb | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb index 3c711b600a..a843eed21f 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb @@ -29,6 +29,8 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release + @droplet.java_opts.add_system_property 'java.endorsed.dirs', + "$PWD/#{endorsed.relative_path_from(@droplet.root)}" end protected diff --git a/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb index c9a767bd7f..3e238e246d 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb @@ -35,8 +35,10 @@ expect(sandbox + "endorsed/tomcat_logging_support-#{version}.jar").to exist end - it 'does nothing during release' do + it 'sets java.endorsed.dirs during release' do component.release + + expect(java_opts).to include('-Djava.endorsed.dirs=$PWD/.java-buildpack/tomcat/endorsed') end end From 31e4cba3d3db825bde04230c53a1b5dc2e5e9f32 Mon Sep 17 00:00:00 2001 From: Violeta Georgieva Date: Fri, 22 Jul 2016 16:40:54 +0300 Subject: [PATCH 182/812] Extract Tomcat 7 compatibility check as a method Extract Tomcat 7 compatibility check to a separate method that can be overridden by the subclasses. [resolves #313] --- .../container/tomcat/tomcat_instance.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index 1c214df98f..31e6a6a996 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -53,14 +53,19 @@ def supports? true end - private - TOMCAT_8 = JavaBuildpack::Util::TokenizedVersion.new('8.0.0').freeze private_constant :TOMCAT_8 + # Checks whether Tomcat instance is Tomcat 7 compatible + def tomcat_7_compatible + @version < TOMCAT_8 + end + + private + def configure_jasper - return unless @version < TOMCAT_8 + return unless tomcat_7_compatible document = read_xml server_xml server = REXML::XPath.match(document, '/Server').first @@ -77,7 +82,7 @@ def configure_linking document = read_xml context_xml context = REXML::XPath.match(document, '/Context').first - if @version < TOMCAT_8 + if tomcat_7_compatible context.add_attribute 'allowLinking', true else context.add_element 'Resources', 'allowLinking' => true From e643ddc5e223987116704126fbf1df7a6e4971fc Mon Sep 17 00:00:00 2001 From: Ekaterina Blatova Date: Thu, 16 Jun 2016 21:52:22 +0300 Subject: [PATCH 183/812] Azul Zulu JRE This change adds Azul Zulu as an alternative JRE. Zulu is a tested and certified build of OpenJDK; see zulu.org for more details. [resolves #303][resolves #306] --- README.md | 1 + config/components.yml | 2 + config/zulu_jre.yml | 44 ++++++++++ docs/jre-zulu_jre.md | 125 +++++++++++++++++++++++++++++ lib/java_buildpack/jre/zulu_jre.rb | 29 +++++++ resources/zulu_jre/bin/killjava.sh | 50 ++++++++++++ 6 files changed, 251 insertions(+) create mode 100755 config/zulu_jre.yml create mode 100755 docs/jre-zulu_jre.md create mode 100755 lib/java_buildpack/jre/zulu_jre.rb create mode 100755 resources/zulu_jre/bin/killjava.sh diff --git a/README.md b/README.md index 594d11d40f..7f8affdcc6 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * Standard JREs * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) * [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration)) + * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) * [Extending](docs/extending.md) * [Application](docs/extending-application.md) * [Droplet](docs/extending-droplet.md) diff --git a/config/components.yml b/config/components.yml index 0bb53ef3ca..e39425505b 100644 --- a/config/components.yml +++ b/config/components.yml @@ -26,10 +26,12 @@ containers: - "JavaBuildpack::Container::Tomcat" # In order to use Oracle JREs instead of OpenJDK, you must comment out the OpenJDK line and uncomment the Oracle line. +# In order to use Zulu JREs instead of OpenJDK, you must comment out the OpenJDK line and uncomment the Zulu line. # Please see the documentation for more detail. jres: - "JavaBuildpack::Jre::OpenJdkJRE" # - "JavaBuildpack::Jre::OracleJRE" +# - "JavaBuildpack::Jre::ZuluJRE" # Frameworks are processed in order. Any Java Opts added by the JavaOpts framework will be specified in the start # command after any Java Opts added by previous frameworks. diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml new file mode 100755 index 0000000000..a8f5d834ad --- /dev/null +++ b/config/zulu_jre.yml @@ -0,0 +1,44 @@ +# Cloud Foundry Java Buildpack +# Copyright 2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for JRE repositories keyed by vendor +# Pre Java 1.8, permgen was used instead of metaspace. Please see the documentation for more detail. + +# You must specify a the repository root of an Zulu JRE repository. Please see the documentation for more detail. +# e.g. repository_root: "http://example.com/zulu-jre/{platform}/{architecture}" +--- +jre: + version: 1.8.0_+ + repository_root: "https://cdn.azul.com/zulu/bin" +memory_calculator: + version: 2.+ + repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' + stack_threads: + memory_sizes: + heap: + metaspace: 64m.. + native: + permgen: 64m.. + stack: + memory_heuristics: + heap: 75 + metaspace: 10 + native: 10 + permgen: 10 + stack: 5 + memory_initials: + heap: 100% + metaspace: 100% + permgen: 100% diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md new file mode 100755 index 0000000000..b81e1a3495 --- /dev/null +++ b/docs/jre-zulu_jre.md @@ -0,0 +1,125 @@ +# Azul Zulu JRE +Azul Zulu JRE provides Java runtimes developed by Azul team. Versions of Java from the `1.6`, `1.7`, and `1.8` levels are available. Unless otherwise configured, the version of Java that will be used is specified in [`config/zulu_jre.yml`][]. + +
+ + + + + + + + +
Detection CriterionUnconditional
Tagsopen-jdk-like-jre=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩
+Tags are printed to standard output by the buildpack detect script. + + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The JRE can be configured by modifying the [`config/zulu_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so, it supports the [version syntax][] defined there. + +To use Zulu JRE instead of OpenJDK without forking java-buildpack, set environment variable: + +`cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::ZuluJRE"]}'` + +`cf restage ` + +| Name | Description +| ---- | ----------- +| `memory_sizes` | Optional memory sizes, described under "Memory Sizes". +| `memory_heuristics` | Default memory size weightings, described under "Memory Weightings". +| `memory_initials` | Initial memory sizes, described under "Memory Initials". +| `repository_root` | The URL of the Zulu repository index ([details][repositories]). +| `version` | The version of Java runtime to use. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. + +### Additional Resources +The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/zulu_jre` directory in the buildpack fork. + +#### JCE Unlimited Strength +To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resources/zulu_jre/lib/security/local_policy.jar`. This file will be overlayed onto the Zulu distribution. + +#### Custom CA Certificates +To add custom SSL certificates, add your `cacerts` file to `resources/zulu_jre/lib/security/cacerts`. This file will be overlayed onto the Zulu distribution. + +### Memory +The total available memory is specified when an application is pushed as part of its configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials`, and/or `stack_threads` mappings. + +Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings next time the application is started. + +Note: If setting an initial Stack size, depending on the version of Java and the operating system used by Cloud Foundry, the JRE will require a minimum `-Xss` value. This value tends to be between `100k` and `250k`. + +#### Memory Sizes +The following optional properties may be specified in the `memory_sizes` mapping. + +| Name | Description +| ---- | ----------- +| `heap` | The maximum heap size to use. It may be a single value, such as `64m` or a range of acceptable values, such as `128m..256m`. It is used to calculate the value of the Java command-line options `-Xmx` and `-Xms`. +| `metaspace` | The maximum Metaspace size to use. It is applicable to versions of Zulu from Java 1.8 onwards. It may be a single value, such as `64m` or a range of acceptable values, such as `128m..256m`. It is used to calculate the value of the Java command-line options `-XX:MaxMetaspaceSize=` and `-XX:MetaspaceSize=`. +| `native` | The amount of memory to reserve for native memory allocation. It should normally be omitted or specified as a range with no upper bound such as `100m..`. It does not correspond to a switch on the Java command line. +| `permgen` | The maximum PermGen size to use. It is applicable to versions of Zulu earlier than Java 1.8. It may be a single value, such as `64m` or a range of acceptable values, such as `128m..256m`. It is used to calculate the value of the Java command-line options `-XX:MaxPermSize=` and `-XX:PermSize=`. +| `stack` | The stack size to use. It may be a single value, such as `2m` or a range of acceptable values, such as `2m..4m`. It is used to calculate the value of the Java command-line option `-Xss`. + +Memory sizes together with _memory weightings_ are used to calculate the amount of memory for each memory type. The calculation is described later. + +Memory sizes consist of a non-negative integer followed by a unit (`k` for kilobytes, `m` for megabytes, `g` for gigabytes; the case is not significant). Only the memory size `0` may be specified without a unit. + +The above memory size properties may be omitted with an empty value, specified as a single value, or specified as a range. Ranges use the syntax `..`, although either bound may be omitted in which case the defaults of zero and the total available memory are used for the lower bound and upper bound, respectively. Examples of ranges are `100m..200m` (any value between 100 and 200 megabytes, inclusive) and `100m..` (any value greater than or equal to 100 megabytes). + +Each form of memory size is equivalent to a range. Omitting a memory size is equivalent to specifying the range `0..`. Specifying a single value is equivalent to specifying the range with that value as both the lower and upper bound, for example `128m` is equivalent to the range `128m..128m`. + +#### Memory Weightings +Memory weightings are configured in the `memory_heuristics` mapping of [`config/zulu_jre.yml`][]. Each weighting is a non-negative number and represents a proportion of the total available memory (represented by the sum of all the weightings),- for example: + +```yaml +memory_heuristics: + heap: 15 + native: 2 + permgen: 5 + stack: 1 +``` + +represent a maximum heap size three times as large as the maximum PermGen size, and so on. + +Memory weightings are used together with memory ranges to calculate the amount of memory for each memory type, as follows. + +#### Memory Initials +Memory initials are configured in the `memory_initials` mapping of [`config/zulu_jre.yml`][]. Each initial is a percentage of the given type of memory. Valid memory types are `heap`, `permgen`, and `metaspace`. For example, the following initials: + +```yaml +memory_initials: + heap: 50% + permgen: 25% +``` + +Given a maximum heap (`Xmx`) of 1G and a maximum permgen (`-XX:MaxPermsize`) of 256M an initial heap (`Xms`) of 512M and an initial permgen (`-XX:Permsize`) of 64M would be used. + +If no initial value is specified for a memory type, the JVM default will be used. + +A value of 100% for each memory types is generally recommended for best performance. Smaller values will potentially preserve unused system memory for other tenants on the same host. Using the G1 garbage collector along with aggressive `MinHeapFreeRatio` and `MaxHeapFreeRatio` values the JVM will actually release unused heap back to the system up to the initial value. + +#### Stack Threads + +The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command-line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory, then it should be specified like in the following example: + +```yaml +stack_threads: 500 +``` + +#### Memory Calculation +Memory calculation happens before every `start` of an application and it is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. + +The total available memory is allocated into heap, Metaspace, or PermGen (depending on the version of Java), stack, and native memory types. + +The total available memory is first allocated to each memory type in proportion to its weighting (this is called 'balancing'). If the resultant size of any memory type lies outside its range, the size is constrained to the range, the constrained size is excluded from the remaining memory, and no further calculation is required for that memory type. The remaining memory is then balanced against the memory types that are left, and the check is repeated until no calculated memory sizes lie outside their ranges. The remaining memory is then allocated to the remaining memory types according to the last balance step. This iteration terminates when none of the sizes of the remaining memory types is constrained by their corresponding ranges. + +Termination is guaranteed since there is a finite number of memory types and in each iteration either none of the remaining memory sizes is constrained by the corresponding range and allocation terminates or at least one memory size is constrained by the corresponding range and it is omitted from the next iteration. + +[`config/components.yml`]: ../config/components.yml +[`config/zulu_jre.yml`]: ../config/zulu_jre.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[Zulu JRE]: jre-zulu_jre.md +[Azul Zulu]: https://www.azul.com/products/zulu/ +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/jre/zulu_jre.rb b/lib/java_buildpack/jre/zulu_jre.rb new file mode 100755 index 0000000000..5b8464ac45 --- /dev/null +++ b/lib/java_buildpack/jre/zulu_jre.rb @@ -0,0 +1,29 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/jre' +require 'java_buildpack/jre/open_jdk_like' + +module JavaBuildpack + module Jre + + # Encapsulates the detect, compile, and release functionality for selecting an Zulu JRE. + class ZuluJRE < OpenJDKLike + end + + end +end diff --git a/resources/zulu_jre/bin/killjava.sh b/resources/zulu_jre/bin/killjava.sh new file mode 100755 index 0000000000..b4b76c93e2 --- /dev/null +++ b/resources/zulu_jre/bin/killjava.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright (c) 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Kill script for use as the parameter of OpenJDK's -XX:OnOutOfMemoryError + +set -e + +echo " +Process Status (Before) +======================= +$(ps -ef) + +ulimit (Before) +=============== +$(ulimit -a) + +Free Disk Space (Before) +======================== +$(df -h) +" + +pkill -9 -f .*-XX:OnOutOfMemoryError=.*killjava.* + +echo " +Process Status (After) +====================== +$(ps -ef) + +ulimit (After) +============== +$(ulimit -a) + +Free Disk Space (After) +======================= +$(df -h) +" From a876fc94a9c4d832b91a4a56895813888e1de1ca Mon Sep 17 00:00:00 2001 From: Alois Mayr Date: Mon, 8 Aug 2016 16:49:19 -0500 Subject: [PATCH 184/812] New framework detection criteria for both Dynatrace frameworks in the buildpack. Made sure that they do not overlap. See updated documentation --- docs/framework-dyna_trace_agent.md | 4 ++-- docs/framework-ruxit_agent.md | 12 ++++++------ lib/java_buildpack/framework/dyna_trace_agent.rb | 4 +++- lib/java_buildpack/framework/ruxit_agent.rb | 2 +- .../framework/dyna_trace_agent_spec.rb | 4 ++++ spec/java_buildpack/framework/ruxit_agent_spec.rb | 2 +- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/docs/framework-dyna_trace_agent.md b/docs/framework-dyna_trace_agent.md index 1f6b438ee9..846ce13cf3 100644 --- a/docs/framework-dyna_trace_agent.md +++ b/docs/framework-dyna_trace_agent.md @@ -12,7 +12,7 @@ The applications Cloud Foundry name is used as the `agent group` in DynaTrace, a Detection CriterionExistence of a single bound DynaTrace service.

    -
  • Existence of a DynaTrace service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has dynatrace as a substring.
  • +
  • Existence of a DynaTrace service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has dynatrace as a substring and contains server field in the credentials. Note: The credentials must NOT contain tenant and tenanttoken in order to make sure the detection mechanism does not interfere with Dynatrace Ruxit integration.
@@ -33,7 +33,7 @@ The credential payload of the service may contain the following entries: | `server` | The DynaTrace collector hostname to connect to. Use `host:port` format for a specific port number. | `profile` | (Optional) The DynaTrace server profile this is associated with. Uses `Monitoring` by default. -**NOTE** +**NOTE** Be sure to open an Application Security Group to your DynaTrace collector prior to starting the application: ``` diff --git a/docs/framework-ruxit_agent.md b/docs/framework-ruxit_agent.md index beea240d92..3c5390e094 100644 --- a/docs/framework-ruxit_agent.md +++ b/docs/framework-ruxit_agent.md @@ -1,13 +1,13 @@ # Dynatrace Ruxit Agent Framework [Dynatrace Ruxit](http://www.dynatrace.com/en/ruxit/) is your full stack monitoring solution - powered by artificial intelligence. Dynatrace Ruxit allows you insights into all application requests from the users click in the browser down to the database statement and code-level. -The Ruxit Agent Framework causes an application to be automatically configured to work with a bound [Ruxit Service][] instance (Free trials available). +The Dynatrace Ruxit Agent Framework causes an application to be automatically configured to work with a bound [Dynatrace Ruxit Service][] instance (Free trials available). - @@ -19,7 +19,7 @@ The Ruxit Agent Framework causes an application to be automatically configured t Tags are printed to standard output by the buildpack detect script ## User-Provided Service -Users must provide their own Ruxit service. A user-provided Ruxit service must have a name or tag with `ruxit` in it so that the Ruxit Agent Framework will automatically configure the application to work with the service. +Users must provide their own Dynatrace Ruxit service. A user-provided Dynatrace Ruxit service must have a name or tag with `dynatrace` or `ruxit` in it so that the Dynatrace Ruxit Agent Framework will automatically configure the application to work with the service. The credential payload of the service may contain the following entries: @@ -42,11 +42,11 @@ The framework can be configured by modifying the [`config/ruxit_agent.yml`][] fi | `version` | The version of Ruxit to use. Candidate versions can be found in [this listing][]. ## Support -This buildpack is currently Beta. If you have any questions or problems regarding the build pack itself please don't hesitate to contact Dynatrace Ruxit on https://answers.ruxit.com/, be sure to use "cloudfoundry" as a topic. +This buildpack extension is currently Beta. If you have any questions or problems regarding the build pack itself please don't hesitate to contact Dynatrace Ruxit on https://answers.ruxit.com/, be sure to use "cloudfoundry" as a topic. [Configuration and Extension]: ../README.md#configuration-and-extension [`config/ruxit_agent.yml`]: ../config/ruxit_agent.yml -[Ruxit Service]: http://www.dynatrace.com/en/ruxit/ +[Dynatrace Ruxit Service]: http://www.dynatrace.com/en/ruxit/ [repositories]: extending-repositories.md [this listing]: https://download.ruxit.com/agent/paas/cloudfoundry/java/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/dyna_trace_agent.rb b/lib/java_buildpack/framework/dyna_trace_agent.rb index 067c59325a..51042743ed 100644 --- a/lib/java_buildpack/framework/dyna_trace_agent.rb +++ b/lib/java_buildpack/framework/dyna_trace_agent.rb @@ -41,7 +41,9 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, 'server' + (@application.services.one_service? FILTER, 'server') && + !(@application.services.one_service? FILTER, 'tenant') && + !(@application.services.one_service? FILTER, 'tenanttoken') end private diff --git a/lib/java_buildpack/framework/ruxit_agent.rb b/lib/java_buildpack/framework/ruxit_agent.rb index bfb452028a..dc9f6c52cf 100644 --- a/lib/java_buildpack/framework/ruxit_agent.rb +++ b/lib/java_buildpack/framework/ruxit_agent.rb @@ -62,7 +62,7 @@ def supports? private - FILTER = /ruxit/.freeze + FILTER = /ruxit|dynatrace/.freeze RUXIT_APPLICATION_ID = 'RUXIT_APPLICATIONID'.freeze diff --git a/spec/java_buildpack/framework/dyna_trace_agent_spec.rb b/spec/java_buildpack/framework/dyna_trace_agent_spec.rb index bd8440fb72..26e4218537 100644 --- a/spec/java_buildpack/framework/dyna_trace_agent_spec.rb +++ b/spec/java_buildpack/framework/dyna_trace_agent_spec.rb @@ -33,6 +33,8 @@ before do allow(services).to receive(:one_service?).with(/dynatrace/, 'server').and_return(true) + allow(services).to receive(:one_service?).with(/dynatrace/, 'tenant').and_return(false) + allow(services).to receive(:one_service?).with(/dynatrace/, 'tenanttoken').and_return(false) allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name' }) end @@ -69,6 +71,8 @@ context do before do allow(services).to receive(:one_service?).with(/dynatrace/, 'server').and_return(true) + allow(services).to receive(:one_service?).with(/dynatrace/, 'tenant').and_return(false) + allow(services).to receive(:one_service?).with(/dynatrace/, 'tenanttoken').and_return(false) allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name', 'profile' => 'test-profile' }) end diff --git a/spec/java_buildpack/framework/ruxit_agent_spec.rb b/spec/java_buildpack/framework/ruxit_agent_spec.rb index 2fa9543494..7d56901544 100644 --- a/spec/java_buildpack/framework/ruxit_agent_spec.rb +++ b/spec/java_buildpack/framework/ruxit_agent_spec.rb @@ -29,7 +29,7 @@ context do before do - allow(services).to receive(:one_service?).with(/ruxit/, 'tenant', 'tenanttoken').and_return(true) + allow(services).to receive(:one_service?).with(/ruxit|dynatrace/, 'tenant', 'tenanttoken').and_return(true) end it 'detects with ruxit-n/a service' do From 6a16fb651922098cafd4046cd507980177c1471d Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 16 Aug 2016 12:36:02 -0700 Subject: [PATCH 185/812] Tomcat Startup Improvements Previously if an application failed to start up with the Tomcat container, Tomcat would still respond positively to health checks. This change, suggested by a Tomcat committer, will ensure that the container will respond negatively to health checks when an application fails to start. --- resources/tomcat/conf/server.xml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/resources/tomcat/conf/server.xml b/resources/tomcat/conf/server.xml index ae8d91a3d9..e8b9a16701 100644 --- a/resources/tomcat/conf/server.xml +++ b/resources/tomcat/conf/server.xml @@ -2,14 +2,14 @@ Creating TrustStore with container certificates' + download_jar - resolved_certificates = certificates - with_timing(caption(resolved_certificates)) do + with_timing("Adding certificates to #{trust_store.relative_path_from(@droplet.root)}") do FileUtils.mkdir_p trust_store.parent - resolved_certificates.each_with_index { |certificate, index| add_certificate certificate, index } + + shell "#{java} -jar #{@droplet.sandbox + jar_name} #{ca_certificates} #{trust_store} #{password}" end end @@ -60,53 +43,31 @@ def release .add_system_property('javax.net.ssl.trustStorePassword', password) end - private + protected - CA_CERTIFICATES = Pathname.new('/etc/ssl/certs/ca-certificates.crt').freeze - - private_constant :CA_CERTIFICATES - - def add_certificate(certificate, index) - @logger.debug { "Adding certificate\n#{certificate}" } - - file = write_certificate certificate - shell "#{keytool} -importcert -noprompt -keystore #{trust_store} -storepass #{password} " \ - "-file #{file.to_path} -alias certificate-#{index}" + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + supports_configuration? && supports_file? end - def ca_certificates - CA_CERTIFICATES - end + private - def caption(resolved_certificates) - "Adding #{resolved_certificates.count} certificates to #{trust_store.relative_path_from(@droplet.root)}" - end + DARWIN_CERTIFICATES = Pathname.new('/etc/ssl/cert.pem').freeze - def certificates - certificates = [] - - certificate = nil - ca_certificates.each_line do |line| - if line =~ /BEGIN CERTIFICATE/ - certificate = line - elsif line =~ /END CERTIFICATE/ - certificate += line - certificates << certificate - certificate = nil - elsif !certificate.nil? - certificate += line - end - end + UNIX_CERTIFICATES = Pathname.new('/etc/ssl/certs/ca-certificates.crt').freeze - certificates - end + private_constant :DARWIN_CERTIFICATES, :UNIX_CERTIFICATES - def id(count) - "#{self.class.to_s.dash_case}=#{count}" + def ca_certificates + if `uname -s` =~ /Darwin/ + DARWIN_CERTIFICATES + else + UNIX_CERTIFICATES + end end - def keytool - @droplet.java_home.root + 'bin/keytool' + def java + @droplet.java_home.root + 'bin/java' end def password @@ -125,13 +86,6 @@ def trust_store @droplet.sandbox + 'truststore.jks' end - def write_certificate(certificate) - file = Tempfile.new('certificate-') - file.write(certificate) - file.fsync - file - end - end end diff --git a/spec/fixtures/stub-container-certificate-trust-store.jar b/spec/fixtures/stub-container-certificate-trust-store.jar new file mode 100644 index 0000000000000000000000000000000000000000..0878c3ccb50e0696f38ae356e9854c75199158f3 GIT binary patch literal 341 zcmWIWW@Zs#;Nak3$ZLM$#DD}i8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1gx0>v$BCyF#%yMkUj+BFaQAGLPY%l literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb b/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb index b561464dc9..bfc911941b 100644 --- a/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb +++ b/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb @@ -28,13 +28,7 @@ it 'detects with ca-certificates file' do allow(component).to receive(:ca_certificates).and_return(ca_certificates) - expect(component.detect).to eq('container-certificate-trust-store=3') - end - - it 'does not detect without ca-certificates file' do - allow(component).to receive(:ca_certificates).and_return(Pathname.new('spec/fixtures/ca-certificates-no-exist.crt')) - - expect(component.detect).to be_nil + expect(component.detect).to eq('container-certificate-trust-store=0.0.0') end context do @@ -47,23 +41,14 @@ end end - it 'creates truststore' do + it 'creates truststore', + cache_fixture: 'stub-container-customizer.jar' do + allow(component).to receive(:ca_certificates).and_return(ca_certificates) - allow(component).to receive(:write_certificate).and_return(Pathname.new('/certificate-0'), - Pathname.new('/certificate-1'), - Pathname.new('/certificate-2')) - allow(component).to receive(:shell).with("#{java_home.root}/bin/keytool -importcert -noprompt " \ - "-keystore #{sandbox}/truststore.jks -storepass " \ - 'java-buildpack-trust-store-password -file /certificate-0 -alias ' \ - 'certificate-0') - allow(component).to receive(:shell).with("#{java_home.root}/bin/keytool -importcert -noprompt " \ - "-keystore #{sandbox}/truststore.jks -storepass " \ - 'java-buildpack-trust-store-password -file /certificate-1 -alias ' \ - 'certificate-1') - allow(component).to receive(:shell).with("#{java_home.root}/bin/keytool -importcert -noprompt " \ - "-keystore #{sandbox}/truststore.jks -storepass " \ - 'java-buildpack-trust-store-password -file /certificate-2 -alias ' \ - 'certificate-2') + allow(component).to receive(:shell).with("#{java_home.root}/bin/java -jar " \ + "#{sandbox}/container_certificate_trust_store-0.0.0.jar " \ + "#{ca_certificates} #{sandbox}/truststore.jks " \ + 'java-buildpack-trust-store-password') component.compile end From 6f25b7e38a09188c9aeb2ff4f26dbbbaa8fdde5e Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 18 Jan 2017 06:07:49 -0800 Subject: [PATCH 216/812] JRE Updates This change updates the buildpack to look at 1.8.0_12+ JREs. --- config/open_jdk_jre.yml | 2 +- config/oracle_jre.yml | 2 +- config/zulu_jre.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 348c0484f2..cc0c19deca 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -17,7 +17,7 @@ # If Java 7 is required, permgen will be used instead of metaspace. Please see the documentation for more detail. --- jre: - version: 1.8.0_11+ + version: 1.8.0_12+ repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" memory_calculator: version: 2.+ diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index 89dab93151..8d9cff7765 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -20,7 +20,7 @@ # e.g. repository_root: "http://example.com/oracle-jre/{platform}/{architecture}" --- jre: - version: 1.8.0_11+ + version: 1.8.0_12+ repository_root: "" memory_calculator: version: 2.+ diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 47cf04098a..47e4b955f3 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -20,7 +20,7 @@ # e.g. repository_root: "http://example.com/zulu-jre/{platform}/{architecture}" --- jre: - version: 1.8.0_11+ + version: 1.8.0_12+ repository_root: "https://cdn.azul.com/zulu/bin" memory_calculator: version: 2.+ From 20b0eb381f67663d03cadacc3666852a40fdbea4 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 23 Jan 2017 11:18:19 -0800 Subject: [PATCH 217/812] Warning when using Java 7 Previously, the buildpack blindly downloaded and installed Java 7 even though it is woefully out of date. Based on user feedback, it was identified that a strong warning to stop doing this would be useful. This change updates the OpenJDK JRE-Like JREs to print that warning message. [resolves #370] --- .idea/.rakeTasks | 2 +- java-buildpack.iml | 2 +- lib/java_buildpack/jre/open_jdk_like_jre.rb | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index 22e60a5ddf..56aac576a4 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/java-buildpack.iml b/java-buildpack.iml index 385a66aeb6..f5598f319a 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -270,7 +270,7 @@ - + diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index c5a012c4ee..5fc0531abf 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -49,6 +49,11 @@ def detect def compile download_tar @droplet.copy_resources + + unless @droplet.java_home.java_8_or_later? + $stderr.puts "\n WARNING: You are using #{@droplet.java_home.version}. Oracle has ended public " \ + "updates of Java 1.7 as of April 2015, possibly rendering your application vulnerable.\n\n" + end end # (see JavaBuildpack::Component::BaseComponent#release) From 3db96e8bb9a3bc7a846facd1b0b3ab473a4a3c7c Mon Sep 17 00:00:00 2001 From: Jonathan Patchell Date: Tue, 24 Jan 2017 09:52:23 -0500 Subject: [PATCH 218/812] Improvements for HA for the Luna Security Provider. * Adding support for HA logging. * Adding HASynchronize section for HA groups. * Fixing reconnect attempts option and changing to max retries. --- config/luna_security_provider.yml | 1 + docs/framework-luna_security_provider.md | 1 + .../framework/luna_security_provider.rb | 24 ++++++++++++++++--- .../Chrystoki.conf | 7 +++++- .../Chrystoki.conf | 9 ++++++- .../framework/luna_security_provider_spec.rb | 2 +- 6 files changed, 38 insertions(+), 6 deletions(-) diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index 5a2a8d7d7a..f3cff841cb 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -18,3 +18,4 @@ version: 6.+ repository_root: http://files.cf-hsm.io/luna-installer logging_enabled: false +ha_logging_enabled: true diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md index d0564d89ca..8b866fede4 100644 --- a/docs/framework-luna_security_provider.md +++ b/docs/framework-luna_security_provider.md @@ -92,6 +92,7 @@ The framework can be configured by modifying the [`config/luna_security_provider | Name | Description | ---- | ----------- | `logging_enabled` | Whether to enable the logging wrapper for the Luna Security Provider. Defaults to `false`. +| `ha_logging_enabled` | Whether to enable HA logging for the Luna Security Provider. Defaults to `true`. | `repository_root` | The URL of the Luna Security Provider repository index ([details][repositories]). | `version` | Version of the Luna Security Provider to use. diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 9bdf60a89d..b506585eba 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -110,6 +110,10 @@ def logging? @configuration['logging_enabled'] end + def ha_logging? + @configuration['ha_logging_enabled'] + end + def padded_index(index) index.to_s.rjust(2, '0') end @@ -144,20 +148,27 @@ def write_configuration(servers, groups) VirtualToken = { EOS groups.each_with_index { |group, index| write_group f, index, group } - write_epilogue f + write_epilogue f, groups end end - def write_epilogue(f) + def write_epilogue(f, groups) f.write < true } } + let(:configuration) { { 'logging_enabled' => true, 'ha_logging_enabled' => true } } it 'writes configuration', cache_fixture: 'stub-luna-security-provider.tar' do From 6d02d1f6b94f512a680e087525de76bc2cb2c15f Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 25 Jan 2017 10:40:25 -0800 Subject: [PATCH 219/812] Polishing [resolves #371] --- config/luna_security_provider.yml | 2 +- docs/framework-luna_security_provider.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index f3cff841cb..6e61d50562 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -17,5 +17,5 @@ --- version: 6.+ repository_root: http://files.cf-hsm.io/luna-installer -logging_enabled: false ha_logging_enabled: true +logging_enabled: false diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md index 8b866fede4..2846a37fb5 100644 --- a/docs/framework-luna_security_provider.md +++ b/docs/framework-luna_security_provider.md @@ -91,8 +91,8 @@ The framework can be configured by modifying the [`config/luna_security_provider | Name | Description | ---- | ----------- -| `logging_enabled` | Whether to enable the logging wrapper for the Luna Security Provider. Defaults to `false`. | `ha_logging_enabled` | Whether to enable HA logging for the Luna Security Provider. Defaults to `true`. +| `logging_enabled` | Whether to enable the logging wrapper for the Luna Security Provider. Defaults to `false`. | `repository_root` | The URL of the Luna Security Provider repository index ([details][repositories]). | `version` | Version of the Luna Security Provider to use. From c912c9969d1ffd359afb69a6169ece250c472e00 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 25 Jan 2017 12:00:20 -0800 Subject: [PATCH 220/812] Include JRE Certificates Previously, the Trust Store Builder only added certificates from the container. This would break compatibility for anyone currently using the JRE's built in trust store to get certificates into the system. This change adds support for getting certificates out of the JRE's cacerts as well. [resolves #372] --- .idea/dictionaries/bhale.xml | 1 + config/container_certificate_trust_store.yml | 2 +- .../framework/container_certificate_trust_store.rb | 8 +++++++- .../framework/container_certificate_trust_store_spec.rb | 7 +++++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 1b7ed1d682..0b69007560 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -8,6 +8,7 @@ argv atpack bootclasspath + cacert chrystoki cklog codeclimate diff --git a/config/container_certificate_trust_store.yml b/config/container_certificate_trust_store.yml index 04435d78c0..2a0f4e60d0 100644 --- a/config/container_certificate_trust_store.yml +++ b/config/container_certificate_trust_store.yml @@ -15,6 +15,6 @@ # Container certificate truststore configuration --- -version: 1.+ +version: 2.+ repository_root: "{default.repository.root}/container-certificate-trust-store" enabled: true diff --git a/lib/java_buildpack/framework/container_certificate_trust_store.rb b/lib/java_buildpack/framework/container_certificate_trust_store.rb index 791bf558f0..8edcf8022e 100644 --- a/lib/java_buildpack/framework/container_certificate_trust_store.rb +++ b/lib/java_buildpack/framework/container_certificate_trust_store.rb @@ -31,7 +31,9 @@ def compile with_timing("Adding certificates to #{trust_store.relative_path_from(@droplet.root)}") do FileUtils.mkdir_p trust_store.parent - shell "#{java} -jar #{@droplet.sandbox + jar_name} #{ca_certificates} #{trust_store} #{password}" + shell "#{java} -jar #{@droplet.sandbox + jar_name} --container-source #{ca_certificates} --destination " \ + "#{trust_store} --destination-password #{password} --jre-source #{cacerts} --jre-source-password " \ + 'changeit' end end @@ -66,6 +68,10 @@ def ca_certificates end end + def cacerts + @droplet.java_home.root + 'lib/security/cacerts' + end + def java @droplet.java_home.root + 'bin/java' end diff --git a/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb b/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb index bfc911941b..a4f29bd8fd 100644 --- a/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb +++ b/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb @@ -47,8 +47,11 @@ allow(component).to receive(:ca_certificates).and_return(ca_certificates) allow(component).to receive(:shell).with("#{java_home.root}/bin/java -jar " \ "#{sandbox}/container_certificate_trust_store-0.0.0.jar " \ - "#{ca_certificates} #{sandbox}/truststore.jks " \ - 'java-buildpack-trust-store-password') + "--container-source #{ca_certificates} " \ + "--destination #{sandbox}/truststore.jks " \ + '--destination-password java-buildpack-trust-store-password ' \ + "--jre-source #{java_home.root}/lib/security/cacerts " \ + '--jre-source-password changeit') component.compile end From d5eb21b11dabb90e0da02650fc47efeb5c2dd923 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 25 Jan 2017 17:00:16 -0800 Subject: [PATCH 221/812] Enforce Permissions During Packaging Previously the packaging task expected that the permissions on the checked out source repository respected what was under source control and that those permissions were carried over to the copy. Since this cannot be dependend on, this change enforces permissions after copy. [resolves #304] --- rakelib/stage_buildpack_task.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rakelib/stage_buildpack_task.rb b/rakelib/stage_buildpack_task.rb index 3e4338fbbc..4445614880 100644 --- a/rakelib/stage_buildpack_task.rb +++ b/rakelib/stage_buildpack_task.rb @@ -37,6 +37,12 @@ def copy_task(source, target) directory parent file(target => [source, parent]) do |t| cp t.source, t.name + + if t.source.start_with? 'bin' + chmod 0755, t.name + else + chmod 0644, t.name + end end target From da9d7b9f72344038ec753bf67823a8366d0660e6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 25 Jan 2017 17:06:03 -0800 Subject: [PATCH 222/812] Memory Heuristic Example A previous change removed the code for an example that modified memory heuristics without removing the reference to it in the prose. This change reinstates that example and polishes the other examples to be consistent. [resolves #301] --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index acb78fea42..0ee02e3d30 100644 --- a/README.md +++ b/README.md @@ -26,33 +26,33 @@ The buildpack supports extension through the use of Git repository forking. The Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec ([Wikipedia] has a good description of this yaml syntax). For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. ```bash -$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{jre: { version: 1.7.0_+ }}' +$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ jre: { version: 1.7.0_+ }, memory_calculator: { memory_heuristics: { heap: 85, stack: 10 } } }' ``` If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. ```bash -$ cf set-env my-application JBP_CONFIG_REPOSITORY '{default_repository_root: "http://repo.example.io"}' +$ cf set-env my-application JBP_CONFIG_REPOSITORY '{ default_repository_root: "http://repo.example.io" }' ``` If the key or value contains an environment variable that you want to bind at runtime you need to escape it from your shell. For example, to add command line arguments containing an environment variable to a [Java Main](docs/container-java_main.md) application. ```bash -$ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{arguments: "-server.port=\$PORT -foo=bar"}' +$ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{ arguments: "-server.port=\$PORT -foo=bar" }' ``` Environment variable can also be specified in the applications `manifest` file. For example, to specify an environment variable in an applications manifest file that disables Auto-reconfiguration. ```bash env: - JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}' + JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{ enabled: false }' ``` This final example shows how to change the version of Tomcat that is used by the buildpack with an environment variable specified in the applications manifest file. ```bash env: - JBP_CONFIG_TOMCAT: '{tomcat: { version: 8.0.+ }}' + JBP_CONFIG_TOMCAT: '{ tomcat: { version: 8.0.+ } }' ``` See the [Environment Variables][] documentation for more information. From 9154e7dab203d07dfcd3423f8630085c7da26cd5 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 25 Jan 2017 17:09:23 -0800 Subject: [PATCH 223/812] Rubocop fixes --- rakelib/stage_buildpack_task.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rakelib/stage_buildpack_task.rb b/rakelib/stage_buildpack_task.rb index 4445614880..097f3d4851 100644 --- a/rakelib/stage_buildpack_task.rb +++ b/rakelib/stage_buildpack_task.rb @@ -39,9 +39,9 @@ def copy_task(source, target) cp t.source, t.name if t.source.start_with? 'bin' - chmod 0755, t.name + chmod 0o755, t.name else - chmod 0644, t.name + chmod 0o644, t.name end end From 81ce49f4b26cbd2dbf4ae1296d19a897b31acfd5 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 26 Jan 2017 15:33:43 -0800 Subject: [PATCH 224/812] NOTICE file update --- NOTICE | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/NOTICE b/NOTICE index 3df9fbf6f3..0bc6e64605 100644 --- a/NOTICE +++ b/NOTICE @@ -1,2 +1,15 @@ - Cloud Foundry Java Buildpack - Copyright 2013-2017 the original author or authors. +Cloud Foundry Java Buildpack + +Copyright (c) 2013-Present CloudFoundry.org Foundation, Inc. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. From 060c619db5634cd8a8c50402a46fabbab4a11db3 Mon Sep 17 00:00:00 2001 From: peer85 Date: Tue, 7 Feb 2017 15:03:51 +0200 Subject: [PATCH 225/812] Update Configuration File This change updates the configuration file to set ha_mode_standby in the configuration file. It does this because using the EKM provided in Cloud Foundry shouldn't randomize HA connections. --- lib/java_buildpack/framework/dyadic_ekm_security_provider.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index a122be5d3f..660e5ae10e 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -110,6 +110,7 @@ def write_conf(servers, send_timeout, recv_timeout, retries) send_timeout = #{send_timeout} recv_timeout = #{recv_timeout} retries = #{retries} +ha_mode_standby = 1 EOS end end From 96550ee1a2f19bed964bc1a3eddf830e0ef7bd44 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 7 Feb 2017 07:52:35 -0800 Subject: [PATCH 226/812] Polishing [resolves #376] --- .../framework/dyadic_ekm_security_provider.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index 660e5ae10e..99370ddff8 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -106,11 +106,11 @@ def write_conf(servers, send_timeout, recv_timeout, retries) FileUtils.mkdir_p conf_file.parent conf_file.open(File::CREAT | File::WRONLY) do |f| f.write < Date: Tue, 7 Feb 2017 07:55:56 -0800 Subject: [PATCH 227/812] Test Fixes --- .../framework_dyadic_ekm_security_provider/client.conf | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spec/fixtures/framework_dyadic_ekm_security_provider/client.conf b/spec/fixtures/framework_dyadic_ekm_security_provider/client.conf index dcf639257c..57ca31a3bb 100644 --- a/spec/fixtures/framework_dyadic_ekm_security_provider/client.conf +++ b/spec/fixtures/framework_dyadic_ekm_security_provider/client.conf @@ -1,4 +1,5 @@ -servers = server-1,server-2 -send_timeout = 3 -recv_timeout = 1 -retries = 2 +servers = server-1,server-2 +send_timeout = 3 +recv_timeout = 1 +retries = 2 +ha_mode_standby = 1 From 34df37206183f6dca7ae55f81e05611fc58748e9 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 14 Feb 2017 16:43:29 -0800 Subject: [PATCH 228/812] New Year of YourKit --- config/your_kit_profiler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml index 402717e4c4..609181e28b 100644 --- a/config/your_kit_profiler.yml +++ b/config/your_kit_profiler.yml @@ -15,7 +15,7 @@ # JMX configuration --- -version: 2016.+ +version: 2017.+ repository_root: "{default.repository.root}/your-kit/{platform}/{architecture}" enabled: false port: 10001 From 58fcfc0598593eb3d17ca01e5f21b47dca092973 Mon Sep 17 00:00:00 2001 From: chrisjdhanley Date: Thu, 9 Feb 2017 23:31:59 -0800 Subject: [PATCH 229/812] ProtectApp Security Provider This change adds support for the ProtectApp Security Provider service. [#385] --- config/components.yml | 3 +- config/protect_app_security_provider.yml | 19 ++ ...framework-protect_app_security_provider.md | 100 +++++++++ .../protect_app_security_provider.rb | 198 ++++++++++++++++++ .../IngrianNAE.properties | 43 ++++ .../stub-protect-app-security-provider.zip | Bin 0 -> 800 bytes .../protect_app_security_provider_spec.rb | 84 ++++++++ 7 files changed, 446 insertions(+), 1 deletion(-) create mode 100644 config/protect_app_security_provider.yml create mode 100644 docs/framework-protect_app_security_provider.md create mode 100644 lib/java_buildpack/framework/protect_app_security_provider.rb create mode 100644 resources/protect_app_security_provider/IngrianNAE.properties create mode 100644 spec/fixtures/stub-protect-app-security-provider.zip create mode 100644 spec/java_buildpack/framework/protect_app_security_provider_spec.rb diff --git a/config/components.yml b/config/components.yml index 76f681c5b8..dd4e9cb643 100644 --- a/config/components.yml +++ b/config/components.yml @@ -52,7 +52,8 @@ frameworks: - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration" - "JavaBuildpack::Framework::PlayFrameworkJPAPlugin" - - "JavaBuildpack::Framework::PostgresqlJDBC" + - "JavaBuildpack::Framework::PostgresqlJDBC + - "JavaBuildpack::Framework::ProtectAppSecurityProvider" - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::YourKitProfiler" diff --git a/config/protect_app_security_provider.yml b/config/protect_app_security_provider.yml new file mode 100644 index 0000000000..1a4246313d --- /dev/null +++ b/config/protect_app_security_provider.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the ProtectApp Security Provider framework +--- +version: 8.4.+ +repository_root: http://files.cf-hsm.io/protectapp-installer diff --git a/docs/framework-protect_app_security_provider.md b/docs/framework-protect_app_security_provider.md new file mode 100644 index 0000000000..f8e9ace0de --- /dev/null +++ b/docs/framework-protect_app_security_provider.md @@ -0,0 +1,100 @@ +# ProtectApp Security Provider Framework +The ProtectApp Security Provider Framework causes an application to be automatically configured to work with a bound [ProtectApp Security Service][]. + +
Detection CriterionExistence of a single bound Ruxit service. + Detection CriterionExistence of a single bound Dynatrace Ruxit service.
    -
  • Existence of a Ruxit service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has ruxit as a substring.
  • +
  • Existence of a Dynatrace Ruxit service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has dynatraceorruxit as a substring.
+ + + + + + + + +
Detection CriterionExistence of a single bound ProtectApp Security Provider service. The existence of an ProtectApp Security service defined by the VCAP_SERVICES payload containing a service name, label or tag with protectapp as a substring. +
Tagsprotect-app-security-provider=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +When binding to the ProtectApp Security Provider using a user-provided service, it must have name or tag with `protectapp` in it. The credential payload can contain the following entries: + +| Name | Description +| ---- | ----------- +| `client` | The client configuration +| `trustedcerts` | An array of certs containing trust information +| `NAE_IP.1` | A list of KeySecure server ips or hostnames to be used +| `***` | (Optional) Any additional entries will be applied as a system property appended to `-Dcom.ingrian.security.nae.` to allow full configuration of the library. + + +#### Client Configuration +| Name | Description +| ---- | ----------- +| `certificate` | A PEM encoded client certificate +| `private-key` | A PEM encoded client private key + +#### Trusted Certs Configuration +One or more PEM encoded certificate + + +### Example Credentials Payload +``` +{ + "client": { + "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----", + "private-key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----", + }, + "trustedcerts": [ + "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" + , + "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" + ], + "NAE_IP.1": "192.168.1.25:192.168.1.26" + +} +``` + +### Creating Credential Payload +In order to create the credentials payload, you should collapse the JSON payload to a single line and set it like the following + +``` +$ cf create-user-provided-service protectapp -p '{"client":{"certificate":"-----BEGIN CERTIFICATE-----\n....\n-----END CERTIFICATE-----","private-key":"-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n"},"trustedcerts":["-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"],NAE_IP.1":"172.17.34.100"} +``` + + +You may want to use a file for this + +Note the client portion is very exacting and needs line breaks in the body every 64 characters. + + 1. The file must contain: + -----BEGIN CERTIFICATE----- + on a separate line (i.e. it must be terminated with a newline). + 2. Each line of "gibberish" must be 64 characters wide. + 3. The file must end with: + -----END CERTIFICATE----- + and also be terminated with a newline. + 4. Don't save the cert text with Word. It must be in ASCII. + 5. Don't mix DOS and UNIX style line terminations. + +So, here are a few steps you can take to normalize your certificate: + 1. Run it through dos2unix + dos2unix cert.pem + 2. Run it through fold + fold -w 64 cert.pem + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/protect_app_security_provider.yml`][] file in the buildpack. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the ProtectApp Security Provider repository index ([details][repositories]). +| `version` | Version of the ProtectApp Security Provider to use. + +### Additional Resources +The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/pprotect_app_security_provider` directory in the buildpack fork. + +[`config/protect_app_security_provider.yml`]: ../config/protect_app_security_provider.yml +[ProtectApp Security Service]: https://safenet.gemalto.com/data-encryption/protectapp-application-protection/ +[Configuration and Extension]: ../README.md#configuration-and-extension +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb new file mode 100644 index 0000000000..0edb4563c4 --- /dev/null +++ b/lib/java_buildpack/framework/protect_app_security_provider.rb @@ -0,0 +1,198 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'shellwords' +require 'tempfile' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/qualify_path' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Safenet ProtectApp Java Security Provider support. + class ProtectAppSecurityProvider < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_zip + + # copy default properties file + @droplet.copy_resources + + credentials = @application.services.find_service(FILTER)['credentials'] + + write_client credentials['client'] + write_trusted_certs credentials['trustedcerts'] + + certificates.each_with_index { |certificate, index| add_certificate certificate, index } + + # setup java keystore with provided values + merge_clientcert + import_clientcert + + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + credentials = @application.services.find_service(FILTER)['credentials'] + java_opts = @droplet.java_opts + configuration = {} + + filter_known_input(credentials, configuration) + + write_java_opts(java_opts, configuration) + @droplet.java_opts + .add_system_property('java.ext.dirs', ext_dirs) + .add_system_property('com.ingrian.security.nae.IngrianNAE_Properties_Conf_Filename', @droplet.sandbox + 'IngrianNAE.properties') + .add_system_property('com.ingrian.security.nae.Key_Store_Location', key_store) + .add_system_property('com.ingrian.security.nae.Key_Store_Password', password) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, 'client', 'trustedcerts' + end + + private + + FILTER = /protectapp/.freeze + + private_constant :FILTER + + def merge_clientcert + + shell "openssl pkcs12 -export -in #{client_certificate} -inkey #{client_private_key} -name #{myclientcert} -out #{myp12} -passout pass:#{password}" + end + + def import_clientcert + + shell "#{keytool} -importkeystore -noprompt -destkeystore #{key_store} -deststorepass #{password} " \ + "-srckeystore #{myp12} -srcstorepass #{password} -srcstoretype pkcs12" \ + " -alias #{myclientcert}" + end + + def add_certificate(certificate, index) + + file = write_certificate certificate + shell "#{keytool} -importcert -noprompt -keystore #{key_store} -storepass #{password} " \ + "-file #{file.to_path} -alias certificate-#{index}" + end + + def certificates + certificates = [] + + certificate = nil + File.open(trusted_certificates).each_line do |line| + if line =~ /BEGIN CERTIFICATE/ + certificate = line + elsif line =~ /END CERTIFICATE/ + certificate += line + certificates << certificate + certificate = nil + elsif !certificate.nil? + certificate += line + end + end + + certificates + end + + def keytool + @droplet.java_home.root + 'bin/keytool' + end + + def password + 'nae-jks-password' + end + + def key_store + @droplet.sandbox + 'keystore.jks' + end + + def write_certificate(certificate) + file = Tempfile.new('certificate-') + file.write(certificate) + file.fsync + file + end + + def ext_dir + @droplet.sandbox + 'ext' + end + + def ext_dirs + "#{qualify_path(@droplet.java_home.root + 'lib/ext', @droplet.root)}:" \ + "#{qualify_path(ext_dir, @droplet.root)}" + end + + def client_certificate + File.join(Dir.tmpdir,'/client-certificate.pem') + end + + def client_private_key + File.join(Dir.tmpdir,'/client-private-key.pem') + end + + def trusted_certificates + File.join(Dir.tmpdir, 'trusted_certificates.pem') + end + + def myclientcert + 'myclientcert' + end + + def myp12 + File.join(Dir.tmpdir,'/clientwrap.p12') + end + + def write_client(client) + File.open(client_certificate, File::CREAT | File::WRONLY) do |f| + f.write "#{client['certificate']}\n" + end + + File.open(client_private_key, File::CREAT | File::WRONLY) do |f| + f.write "#{client['private-key']}\n" + end + end + + def write_trusted_certs(trusted_certs) + File.open(trusted_certificates,File::CREAT | File::WRONLY) do |f| + trusted_certs.each { |cert| f.write "#{cert}\n" } + end + end + + def filter_known_input(credentials, configuration) + credentials.each do |key, value| + if key != "client" and key != "trustedcerts" + configuration[key] = value + end + end + end + + def write_java_opts(java_opts, configuration2) + configuration2.each do |key, value| + java_opts.add_system_property("com.ingrian.security.nae.#{key}", value ) + end + end + + end + end +end diff --git a/resources/protect_app_security_provider/IngrianNAE.properties b/resources/protect_app_security_provider/IngrianNAE.properties new file mode 100644 index 0000000000..be9e361c04 --- /dev/null +++ b/resources/protect_app_security_provider/IngrianNAE.properties @@ -0,0 +1,43 @@ +Version=2.4 +NAE_IP.1= +NAE_Port=9000 +KMIP_Port=5696 +Protocol=ssl +Verify_SSL_Certificate=no +SSL_Handshake_Timeout= +Use_Persistent_Connections=yes +Size_of_Connection_Pool=300 +Load_Balancing_Algorithm=round-robin +Connection_Idle_Timeout=600000 +Unreachable_Server_Retry_Period=60000 +Maximum_Server_Retry_Period=0 +Connection_Timeout=30000 +Connection_Read_Timeout=7000 +Connection_Retry_Interval=600000 +Client_Cert_Alias= +Client_Cert_Passphrase= +Key_Store_Location= +Key_Store_Password= +Cluster_Synchronization_Delay=100 +Symmetric_Key_Cache_Enabled=no +Asymmetric_Key_Cache_Enabled=no +Symmetric_Key_Cache_Expiry=43200 +Local_Cipher_Cache_Expiry=-1 +Local_Crypto_Provider= +Persistent_Cache_Enabled=no +Persistent_Cache_Expiry_Keys=43200 +Persistent_Cache_Directory= +Persistent_Cache_Max_Size=100 +FIPS_Mode=off +Credentials_Encrypted=no +Passphrase_Encrypted=no +Log_Level=NONE +Log_File= +Log_Rotation=Daily +Log_GMT=no +Log_Size_Limit=100k +SysLog_IP= +SysLog_Port= +Log_Config_Advanced= +Key_non_exportable_policy=no +Log_MaxBackupIndex=-1 diff --git a/spec/fixtures/stub-protect-app-security-provider.zip b/spec/fixtures/stub-protect-app-security-provider.zip new file mode 100644 index 0000000000000000000000000000000000000000..b116d22593b28767bd53283c8929ec006802e249 GIT binary patch literal 800 zcmWIWW@h1H00HePcP}slN=O0eq~wC4{4(9tiW1$dlx#!O{5)MlQzN~s#G(M4`gnl) z(u;vAjr0uhtCRq$^vp{y%1q45$xk=Q(oHPLB&Lt`ky6to zP)tt(nvN^zDYZ!w#ikkPHX%nBrB;cdSalv@6 { '#{NAE_IP.1}' => 'server_ip', + '#{foo}' => 'bar' }) + + component.release + + expect(java_opts).to include('-Dcom.ingrian.security.nae.NAE_IP.1=server_ip') + expect(java_opts).to include('-Dcom.ingrian.security.nae.foo=bar') + end + + end +end From dffe22a3376de40fb7b4a07ad27c00bd4a53fbba Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 22 Feb 2017 12:43:33 -0800 Subject: [PATCH 230/812] Polishing This change polishes up the contribution to be a bit more idomatic for the project. [#385] --- README.md | 1 + config/components.yml | 2 +- ...framework-protect_app_security_provider.md | 50 +++-- .../protect_app_security_provider.rb | 174 ++++++------------ .../java.security | 1 + .../stub-protect-app-security-provider.zip | Bin 800 -> 1052 bytes .../protect_app_security_provider_spec.rb | 77 +++++--- 7 files changed, 132 insertions(+), 173 deletions(-) create mode 100644 resources/protect_app_security_provider/java.security diff --git a/README.md b/README.md index 0ee02e3d30..0a2e76763e 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) * [Play Framework JPA Plugin](docs/framework-play_framework_jpa_plugin.md) ([Configuration](docs/framework-play_framework_jpa_plugin.md#configuration)) * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) + * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) * [Spring Insight](docs/framework-spring_insight.md) * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) diff --git a/config/components.yml b/config/components.yml index dd4e9cb643..88024998f9 100644 --- a/config/components.yml +++ b/config/components.yml @@ -52,7 +52,7 @@ frameworks: - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration" - "JavaBuildpack::Framework::PlayFrameworkJPAPlugin" - - "JavaBuildpack::Framework::PostgresqlJDBC + - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::ProtectAppSecurityProvider" - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" diff --git a/docs/framework-protect_app_security_provider.md b/docs/framework-protect_app_security_provider.md index f8e9ace0de..b1dd5d6d4e 100644 --- a/docs/framework-protect_app_security_provider.md +++ b/docs/framework-protect_app_security_provider.md @@ -1,5 +1,5 @@ # ProtectApp Security Provider Framework -The ProtectApp Security Provider Framework causes an application to be automatically configured to work with a bound [ProtectApp Security Service][]. +The ProtectApp Security Provider Framework causes an application to be automatically configured to work with a bound [ProtectApp Security Service][]. @@ -20,35 +20,31 @@ When binding to the ProtectApp Security Provider using a user-provided service, | Name | Description | ---- | ----------- | `client` | The client configuration -| `trustedcerts` | An array of certs containing trust information +| `trusted_certificates` | An array of certs containing trust information | `NAE_IP.1` | A list of KeySecure server ips or hostnames to be used | `***` | (Optional) Any additional entries will be applied as a system property appended to `-Dcom.ingrian.security.nae.` to allow full configuration of the library. - #### Client Configuration | Name | Description | ---- | ----------- | `certificate` | A PEM encoded client certificate -| `private-key` | A PEM encoded client private key +| `private_key` | A PEM encoded client private key #### Trusted Certs Configuration -One or more PEM encoded certificate - +One or more PEM encoded certificate ### Example Credentials Payload ``` { "client": { "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----", - "private-key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----", + "private_key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----" }, - "trustedcerts": [ - "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" - , + "trusted_certificates": [ + "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" ], "NAE_IP.1": "192.168.1.25:192.168.1.26" - } ``` @@ -56,29 +52,29 @@ One or more PEM encoded certificate In order to create the credentials payload, you should collapse the JSON payload to a single line and set it like the following ``` -$ cf create-user-provided-service protectapp -p '{"client":{"certificate":"-----BEGIN CERTIFICATE-----\n....\n-----END CERTIFICATE-----","private-key":"-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n"},"trustedcerts":["-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"],NAE_IP.1":"172.17.34.100"} +$ cf create-user-provided-service protectapp -p '{"client":{"certificate":"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----","private_key":"-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"},"trusted_certificates":["-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----","-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"],"NAE_IP.1":"192.168.1.25:192.168.1.26"}' ``` - You may want to use a file for this Note the client portion is very exacting and needs line breaks in the body every 64 characters. - 1. The file must contain: - -----BEGIN CERTIFICATE----- - on a separate line (i.e. it must be terminated with a newline). - 2. Each line of "gibberish" must be 64 characters wide. - 3. The file must end with: - -----END CERTIFICATE----- - and also be terminated with a newline. - 4. Don't save the cert text with Word. It must be in ASCII. - 5. Don't mix DOS and UNIX style line terminations. +1. The file must contain: +`-----BEGIN CERTIFICATE-----` +on a separate line (i.e. it must be terminated with a newline). +1. Each line of "gibberish" must be 64 characters wide. +1. The file must end with: +`-----END CERTIFICATE-----` +and also be terminated with a newline. +1. Don't save the cert text with Word. It must be in ASCII. +1. Don't mix DOS and UNIX style line terminations. So, here are a few steps you can take to normalize your certificate: - 1. Run it through dos2unix - dos2unix cert.pem - 2. Run it through fold - fold -w 64 cert.pem + +1. Run it through `dos2unix` +`$ dos2unix cert.pem` +1. Run it through `fold` +`$ fold -w 64 cert.pem` ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. @@ -91,7 +87,7 @@ The framework can be configured by modifying the [`config/protect_app_security_p | `version` | Version of the ProtectApp Security Provider to use. ### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/pprotect_app_security_provider` directory in the buildpack fork. +The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/protect_app_security_provider` directory in the buildpack fork. [`config/protect_app_security_provider.yml`]: ../config/protect_app_security_provider.yml [ProtectApp Security Service]: https://safenet.gemalto.com/data-encryption/protectapp-application-protection/ diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb index 0edb4563c4..ce0c2fd5ed 100644 --- a/lib/java_buildpack/framework/protect_app_security_provider.rb +++ b/lib/java_buildpack/framework/protect_app_security_provider.rb @@ -30,108 +30,61 @@ class ProtectAppSecurityProvider < JavaBuildpack::Component::VersionedDependency # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_zip - - # copy default properties file + download_zip false @droplet.copy_resources credentials = @application.services.find_service(FILTER)['credentials'] - - write_client credentials['client'] - write_trusted_certs credentials['trustedcerts'] - - certificates.each_with_index { |certificate, index| add_certificate certificate, index } - - # setup java keystore with provided values - merge_clientcert - import_clientcert - + + pkcs12 = merge_client_credentials credentials['client'] + add_client_credentials pkcs12 + + add_trusted_certificates credentials['trusted_certificates'] end # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER)['credentials'] java_opts = @droplet.java_opts - configuration = {} - - filter_known_input(credentials, configuration) - - write_java_opts(java_opts, configuration) - @droplet.java_opts + + java_opts .add_system_property('java.ext.dirs', ext_dirs) - .add_system_property('com.ingrian.security.nae.IngrianNAE_Properties_Conf_Filename', @droplet.sandbox + 'IngrianNAE.properties') - .add_system_property('com.ingrian.security.nae.Key_Store_Location', key_store) + .add_system_property('java.security.properties', @droplet.sandbox + 'java.security') + .add_system_property('com.ingrian.security.nae.IngrianNAE_Properties_Conf_Filename', + @droplet.sandbox + 'IngrianNAE.properties') + .add_system_property('com.ingrian.security.nae.Key_Store_Location', keystore) .add_system_property('com.ingrian.security.nae.Key_Store_Password', password) + + credentials + .reject { |key, _| key =~ /^client$/ || key =~ /^trusted_certificates$/ } + .each { |key, value| java_opts.add_system_property("com.ingrian.security.nae.#{key}", value) } end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, 'client', 'trustedcerts' + @application.services.one_service? FILTER, 'client', 'trusted_certificates' end private - FILTER = /protectapp/.freeze + FILTER = /protectapp/ private_constant :FILTER - - def merge_clientcert - - shell "openssl pkcs12 -export -in #{client_certificate} -inkey #{client_private_key} -name #{myclientcert} -out #{myp12} -passout pass:#{password}" - end - - def import_clientcert - - shell "#{keytool} -importkeystore -noprompt -destkeystore #{key_store} -deststorepass #{password} " \ - "-srckeystore #{myp12} -srcstorepass #{password} -srcstoretype pkcs12" \ - " -alias #{myclientcert}" - end - def add_certificate(certificate, index) - - file = write_certificate certificate - shell "#{keytool} -importcert -noprompt -keystore #{key_store} -storepass #{password} " \ - "-file #{file.to_path} -alias certificate-#{index}" - end - - def certificates - certificates = [] - - certificate = nil - File.open(trusted_certificates).each_line do |line| - if line =~ /BEGIN CERTIFICATE/ - certificate = line - elsif line =~ /END CERTIFICATE/ - certificate += line - certificates << certificate - certificate = nil - elsif !certificate.nil? - certificate += line - end - end - - certificates - end - - def keytool - @droplet.java_home.root + 'bin/keytool' - end - - def password - 'nae-jks-password' + def add_client_credentials(pkcs12) + shell "#{keytool} -importkeystore -noprompt -destkeystore #{keystore} -deststorepass #{password} " \ + "-srckeystore #{pkcs12.path} -srcstorepass #{password} -srcstoretype pkcs12" \ + " -alias #{File.basename(pkcs12)}" end - def key_store - @droplet.sandbox + 'keystore.jks' - end + def add_trusted_certificates(trusted_certificates) + trusted_certificates.each do |certificate| + pem = write_certificate certificate - def write_certificate(certificate) - file = Tempfile.new('certificate-') - file.write(certificate) - file.fsync - file + shell "#{keytool} -importcert -noprompt -keystore #{keystore} -storepass #{password} " \ + "-file #{pem.path} -alias #{File.basename(pem)}" + end end def ext_dir @@ -142,54 +95,45 @@ def ext_dirs "#{qualify_path(@droplet.java_home.root + 'lib/ext', @droplet.root)}:" \ "#{qualify_path(ext_dir, @droplet.root)}" end - - def client_certificate - File.join(Dir.tmpdir,'/client-certificate.pem') - end - def client_private_key - File.join(Dir.tmpdir,'/client-private-key.pem') + def keystore + @droplet.sandbox + 'nae-keystore.jks' end - def trusted_certificates - File.join(Dir.tmpdir, 'trusted_certificates.pem') - end - - def myclientcert - 'myclientcert' - end - - def myp12 - File.join(Dir.tmpdir,'/clientwrap.p12') + def keytool + @droplet.java_home.root + 'bin/keytool' end - def write_client(client) - File.open(client_certificate, File::CREAT | File::WRONLY) do |f| - f.write "#{client['certificate']}\n" - end + def merge_client_credentials(credentials) + certificate = write_certificate credentials['certificate'] + private_key = write_private_key credentials['private_key'] - File.open(client_private_key, File::CREAT | File::WRONLY) do |f| - f.write "#{client['private-key']}\n" - end + pkcs12 = Tempfile.new('pkcs12-') + pkcs12.close + + shell "openssl pkcs12 -export -in #{certificate.path} -inkey #{private_key.path} " \ + "-name #{File.basename(pkcs12)} -out #{pkcs12.path} -passout pass:#{password}" + + pkcs12 end - - def write_trusted_certs(trusted_certs) - File.open(trusted_certificates,File::CREAT | File::WRONLY) do |f| - trusted_certs.each { |cert| f.write "#{cert}\n" } - end + + def password + 'nae-keystore-password' end - - def filter_known_input(credentials, configuration) - credentials.each do |key, value| - if key != "client" and key != "trustedcerts" - configuration[key] = value - end + + def write_certificate(certificate) + Tempfile.open('certificate-') do |f| + f.write "#{certificate}\n" + f.sync + f end - end - - def write_java_opts(java_opts, configuration2) - configuration2.each do |key, value| - java_opts.add_system_property("com.ingrian.security.nae.#{key}", value ) + end + + def write_private_key(private_key) + Tempfile.open('private-key-') do |f| + f.write "#{private_key}\n" + f.sync + f end end diff --git a/resources/protect_app_security_provider/java.security b/resources/protect_app_security_provider/java.security new file mode 100644 index 0000000000..7c57d3829c --- /dev/null +++ b/resources/protect_app_security_provider/java.security @@ -0,0 +1 @@ +security.provider.10=com.ingrian.security.nae.IngrianProvider diff --git a/spec/fixtures/stub-protect-app-security-provider.zip b/spec/fixtures/stub-protect-app-security-provider.zip index b116d22593b28767bd53283c8929ec006802e249..0ae4e7d3fb5001d50dc83336aa993c712d40beff 100644 GIT binary patch literal 1052 zcmWIWW@h1H00GO$FfT9zO0Y1CA2I*#{WE-01=jj@n8tG*v7J88q{nEC)}D()mfx(%`@Hkbi(4k(mSY(PyOq+20@Vnr{i6=+EXm+7o* TK)*Av0iik*1H*lw84L^nz~aT- literal 800 zcmWIWW@h1H00HePcP}slN=O0eq~wC4{4(9tiW1$dlx#!O{5)MlQzN~s#G(M4`gnl) z(u;vAjr0uhtCRq$^vp{y%1q45$xk=Q(oHPLB&Lt`ky6to zP)tt(nvN^zDYZ!w#ikkPHX%nBrB;cdSalv@6 { + 'client' => { + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", + 'private_key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----" + }, + 'trusted_certificates' => [ + "-----BEGIN CERTIFICATE-----\ntest-server-1-cert\n-----END CERTIFICATE-----", + "-----BEGIN CERTIFICATE-----\ntest-server-2-cert\n-----END CERTIFICATE-----" + ], + 'NAE_IP.1' => 'server_ip', + 'foo' => 'bar' + } + ) end it 'detects with protectapp-n/a service' do - expect(component.detect).to eq("protectapp-security-provider=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-protectapp-security-provider.zip' do - - component.compile - - expect(sandbox + 'IngrianNAE.properties').to exist + expect(component.detect).to eq("protect-app-security-provider=#{version}") end it 'unpacks the protectapp zip', - cache_fixture: 'stub-protectapp-security-provider.zip' do + cache_fixture: 'stub-protect-app-security-provider.zip' do + + allow(component).to receive(:shell).with(start_with('unzip -qq')).and_call_original + allow(component).to receive(:shell).with(start_with('openssl pkcs12')) + allow(component).to receive(:shell).with(start_with("#{java_home.root}/bin/keytool -importkeystore")) + allow(component).to receive(:shell).with(start_with("#{java_home.root}/bin/keytool -importcert")) component.compile - expect(sandbox + 'IngrianNAE-#{version}.jar').to exist - expect(sandbox + 'Ingrianlog4j-core-2.1.jar').to exist - expect(sandbox + 'Ingrianlog4j-api-2.1.jar').to exist + expect(sandbox + "ext/IngrianNAE-#{version}.jar").to exist + expect(sandbox + 'ext/Ingrianlog4j-core-2.1.jar').to exist + expect(sandbox + 'ext/Ingrianlog4j-api-2.1.jar').to exist end - it 'write certificate files', - cache_fixture: 'stub-protectapp-security-provider.zip' do + it 'copies resources', + cache_fixture: 'stub-protect-app-security-provider.zip' do + + allow(component).to receive(:shell).with(start_with('unzip -qq')).and_call_original + allow(component).to receive(:shell).with(start_with('openssl pkcs12')) + allow(component).to receive(:shell).with(start_with("#{java_home.root}/bin/keytool -importkeystore")) + allow(component).to receive(:shell).with(start_with("#{java_home.root}/bin/keytool -importcert")) component.compile - expect(sandbox + 'client-certificate.pem').to exist - expect(sandbox + 'client-private-key.pem').to exist - expect(sandbox + 'trusted_certificates.pem').to exist - expect(sandbox + 'clientwrap.p12').to exist - - # transfer to keystore - expect(sandbox + 'keystore.jks').to exist - + expect(sandbox + 'IngrianNAE.properties').to exist end - it 'updates JAVA_OPTS with additional options' do - allow(services).to receive(:find_service).and_return('credentials' => { '#{NAE_IP.1}' => 'server_ip', - '#{foo}' => 'bar' }) - component.release + expect(java_opts).to include('-Djava.ext.dirs=$PWD/.test-java-home/lib/ext:' \ + '$PWD/.java-buildpack/protect_app_security_provider/ext') + expect(java_opts).to include('-Djava.security.properties=' \ + '$PWD/.java-buildpack/protect_app_security_provider/java.security') + expect(java_opts).to include('-Dcom.ingrian.security.nae.IngrianNAE_Properties_Conf_Filename=' \ + '$PWD/.java-buildpack/protect_app_security_provider/IngrianNAE.properties') + expect(java_opts).to include('-Dcom.ingrian.security.nae.Key_Store_Location=' \ + '$PWD/.java-buildpack/protect_app_security_provider/nae-keystore.jks') + expect(java_opts).to include('-Dcom.ingrian.security.nae.Key_Store_Password=nae-keystore-password') expect(java_opts).to include('-Dcom.ingrian.security.nae.NAE_IP.1=server_ip') expect(java_opts).to include('-Dcom.ingrian.security.nae.foo=bar') + + expect(java_opts).not_to include(start_with('-Dcom.ingrian.security.nae.client')) + expect(java_opts).not_to include(start_with('-Dcom.ingrian.security.nae.trusted_certificates')) end end From d5d58c609bea2a582030ebd4f28de9fd8572bbab Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 1 Mar 2017 14:24:18 +0000 Subject: [PATCH 231/812] Improve Documentation This change updates the documentation of Oracle JRE to describe how to use it without a buildpack fork. [resolves #383] --- docs/jre-oracle_jre.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 7441af9657..14bb171c06 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -27,6 +27,13 @@ For general information on configuring the buildpack, including how to specify c The JRE can be configured by modifying the [`config/oracle_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. +To use Oracle JRE instead of OpenJDK without forking java-buildpack, set environment variable: + +`cf set-env JBP_CONFIG_COMPONENTS '{ jres: [ "JavaBuildpack::Jre::OracleJRE" ] }'` +`cf set-env JBP_CONFIG_ORACLE_JRE '{ jre: { repository_root: "" } }'` + +`cf restage ` + | Name | Description | ---- | ----------- | `memory_sizes` | Optional memory sizes, described below under "Memory Sizes". From b70d7588e83b88ebc8c111b590652a4d782ee350 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 2 Mar 2017 09:32:01 +0000 Subject: [PATCH 232/812] Ruby Version Updates This change updates the versions of Ruby installed in the CI Docker Image. In addition to updating the versions of 2.2.x and 2.3.x, it adds the newly released 2.4.x in preparation for a future change to use it. --- .ruby-version | 2 +- ci/docker-image/Dockerfile | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.ruby-version b/.ruby-version index 21bb5e156f..bda8fbec15 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.2.5 +2.2.6 diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 65b1f39006..27b2902a2c 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -30,7 +30,10 @@ RUN eval "$(rbenv init -)" \ && echo 'bundler' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ -&& rbenv install 2.2.5 + && rbenv install 2.2.6 RUN eval "$(rbenv init -)" \ -&& rbenv install 2.3.1 + && rbenv install 2.3.3 + +RUN eval "$(rbenv init -)" \ + && rbenv install 2.4.0 From 69ac3010bfd935b717508b19e61843d6646368cf Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 2 Mar 2017 11:42:48 +0000 Subject: [PATCH 233/812] Version Updates This change updates the versions of the dependencies. Making these updates (specifically rubocop) necessitated updates to some of the code. These code changes have been made as well. --- .gitignore | 1 - .idea/misc.xml | 2 +- .../{All_Tests.xml => All_Tests__2_2_.xml} | 2 +- .idea/runConfigurations/All_Tests__2_3_.xml | 36 +++++++++++ .idea/runConfigurations/All_Tests__2_4_.xml | 36 +++++++++++ ...ml => Without_Integration_Tests__2_2_.xml} | 2 +- .../Without_Integration_Tests__2_3_.xml | 36 +++++++++++ .../Without_Integration_Tests__2_4_.xml | 36 +++++++++++ .rubocop.yml | 16 +++-- Gemfile | 2 - Gemfile.lock | 45 ++++++-------- java-buildpack.iml | 59 +++++++++---------- lib/java_buildpack/component/application.rb | 2 +- .../container/tomcat/gemfire/gemfire.rb | 3 +- .../tomcat/gemfire/gemfire_log4j_api.rb | 3 +- .../tomcat/gemfire/gemfire_log4j_core.rb | 3 +- .../tomcat/gemfire/gemfire_log4j_jcl.rb | 3 +- .../tomcat/gemfire/gemfire_log4j_jul.rb | 3 +- .../gemfire/gemfire_log4j_slf4j_impl.rb | 3 +- .../tomcat/gemfire/gemfire_logging.rb | 3 +- .../tomcat/gemfire/gemfire_logging_api.rb | 3 +- .../tomcat/gemfire/gemfire_modules.rb | 3 +- .../tomcat/gemfire/gemfire_modules_tomcat7.rb | 3 +- .../tomcat/gemfire/gemfire_security.rb | 3 +- .../tomcat/tomcat_external_configuration.rb | 3 +- .../tomcat/tomcat_insight_support.rb | 6 +- .../container/tomcat/tomcat_instance.rb | 3 +- .../tomcat/tomcat_lifecycle_support.rb | 3 +- .../container/tomcat/tomcat_redis_store.rb | 3 +- lib/java_buildpack/framework/debug.rb | 3 +- .../framework/introscope_agent.rb | 5 +- lib/java_buildpack/framework/jmx.rb | 3 +- lib/java_buildpack/jre/open_jdk_like_jre.rb | 8 +-- .../util/cache/download_cache.rb | 15 +++-- .../util/configuration_utils.rb | 2 +- lib/java_buildpack/util/filtering_pathname.rb | 16 ++--- rakelib/dependency_cache_task.rb | 2 +- .../container/long_detect_tags.rb | 6 +- spec/java_buildpack/buildpack_spec.rb | 22 +++---- .../component/additional_libraries_spec.rb | 16 ++--- .../container/java_main_spec.rb | 18 +++--- .../container/tomcat/tomcat_instance_spec.rb | 18 +++--- spec/java_buildpack/framework/debug_spec.rb | 7 +-- .../util/cache/download_cache_spec.rb | 4 +- .../util/play/pre22_dist_spec.rb | 18 +++--- .../util/play/pre22_staged_spec.rb | 16 ++--- spec/spec_helper.rb | 8 --- 47 files changed, 309 insertions(+), 204 deletions(-) rename .idea/runConfigurations/{All_Tests.xml => All_Tests__2_2_.xml} (95%) create mode 100644 .idea/runConfigurations/All_Tests__2_3_.xml create mode 100644 .idea/runConfigurations/All_Tests__2_4_.xml rename .idea/runConfigurations/{Without_Integration_Tests.xml => Without_Integration_Tests__2_2_.xml} (96%) create mode 100644 .idea/runConfigurations/Without_Integration_Tests__2_3_.xml create mode 100644 .idea/runConfigurations/Without_Integration_Tests__2_4_.xml diff --git a/.gitignore b/.gitignore index 63c17b0afd..2ac22b33dc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ .idea/workspace.xml .yardoc build/ -coverage doc diff --git a/.idea/misc.xml b/.idea/misc.xml index ba81905e62..ee819f1d8b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,5 +4,5 @@ - + \ No newline at end of file diff --git a/.idea/runConfigurations/All_Tests.xml b/.idea/runConfigurations/All_Tests__2_2_.xml similarity index 95% rename from .idea/runConfigurations/All_Tests.xml rename to .idea/runConfigurations/All_Tests__2_2_.xml index 4762424e81..0f31a50950 100644 --- a/.idea/runConfigurations/All_Tests.xml +++ b/.idea/runConfigurations/All_Tests__2_2_.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_3_.xml b/.idea/runConfigurations/All_Tests__2_3_.xml new file mode 100644 index 0000000000..ae92d24c95 --- /dev/null +++ b/.idea/runConfigurations/All_Tests__2_3_.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/All_Tests__2_4_.xml b/.idea/runConfigurations/All_Tests__2_4_.xml new file mode 100644 index 0000000000..1ad04203f5 --- /dev/null +++ b/.idea/runConfigurations/All_Tests__2_4_.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Without_Integration_Tests.xml b/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml similarity index 96% rename from .idea/runConfigurations/Without_Integration_Tests.xml rename to .idea/runConfigurations/Without_Integration_Tests__2_2_.xml index ddbc97e621..c700635527 100644 --- a/.idea/runConfigurations/Without_Integration_Tests.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml new file mode 100644 index 0000000000..aa696c0cea --- /dev/null +++ b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml new file mode 100644 index 0000000000..a2a4c83c9c --- /dev/null +++ b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.rubocop.yml b/.rubocop.yml index 59ef39482c..9fe2b8978e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,13 +3,15 @@ require: rubocop-rspec AllCops: Include: - - '**/Rakefile' - - 'rakelib/**/*' + - '**/Rakefile' + - 'rakelib/**/*' Exclude: - - 'build/**/*' - - 'vendor/**/*' + - 'build/**/*' Metrics/AbcSize: Max: 22 +Metrics/BlockLength: + Exclude: + - 'spec/**/*.rb' Metrics/ClassLength: Max: 250 Metrics/CyclomaticComplexity: @@ -26,17 +28,19 @@ RSpec/ExampleLength: Max: 20 RSpec/AnyInstance: Enabled: false +RSpec/ExpectOutput: + Enabled: false RSpec/FilePath: Enabled: false RSpec/MultipleExpectations: Enabled: false RSpec/NestedGroups: - MaxNesting: 4 + Max: 4 Style/Documentation: Enabled: false Style/EmptyLinesAroundBlockBody: Exclude: - - 'spec/**/*' + - 'spec/**/*.rb' Style/EmptyLinesAroundClassBody: Enabled: false Style/EmptyLinesAroundModuleBody: diff --git a/Gemfile b/Gemfile index 0dccab2b8f..a5930cc0a2 100644 --- a/Gemfile +++ b/Gemfile @@ -1,14 +1,12 @@ source 'https://rubygems.org' group :development do - gem 'codeclimate-test-reporter' gem 'rake' gem 'redcarpet' gem 'rspec' gem 'rubocop' gem 'rubocop-rspec' gem 'rubyzip' - gem 'simplecov' gem 'tee' gem 'webmock' gem 'yard' diff --git a/Gemfile.lock b/Gemfile.lock index 682c575ace..229ae31083 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,27 +1,25 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.4.0) + addressable (2.5.0) + public_suffix (~> 2.0, >= 2.0.2) ast (2.3.0) - codeclimate-test-reporter (0.6.0) - simplecov (>= 0.7.1, < 1.0.0) crack (0.4.3) safe_yaml (~> 1.0.0) - diff-lcs (1.2.5) - docile (1.1.5) - hashdiff (0.3.0) - json (2.0.2) - parser (2.3.1.2) + diff-lcs (1.3) + hashdiff (0.3.2) + parser (2.4.0.0) ast (~> 2.2) powerpack (0.1.1) - rainbow (2.1.0) - rake (11.2.2) - redcarpet (3.3.4) + public_suffix (2.0.5) + rainbow (2.2.1) + rake (12.0.0) + redcarpet (3.4.0) rspec (3.5.0) rspec-core (~> 3.5.0) rspec-expectations (~> 3.5.0) rspec-mocks (~> 3.5.0) - rspec-core (3.5.2) + rspec-core (3.5.4) rspec-support (~> 3.5.0) rspec-expectations (3.5.0) diff-lcs (>= 1.2.0, < 2.0) @@ -30,45 +28,38 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.5.0) rspec-support (3.5.0) - rubocop (0.42.0) - parser (>= 2.3.1.1, < 3.0) + rubocop (0.47.1) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.7.0) + rubocop-rspec (1.12.0) rubocop (>= 0.42.0) ruby-progressbar (1.8.1) - rubyzip (1.2.0) + rubyzip (1.2.1) safe_yaml (1.0.4) - simplecov (0.12.0) - docile (~> 1.1.0) - json (>= 1.8, < 3) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.0) tee (1.0.0) - unicode-display_width (1.1.0) - webmock (2.1.0) + unicode-display_width (1.1.3) + webmock (2.3.2) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - yard (0.9.5) + yard (0.9.8) PLATFORMS ruby DEPENDENCIES - codeclimate-test-reporter rake redcarpet rspec rubocop rubocop-rspec rubyzip - simplecov tee webmock yard BUNDLED WITH - 1.12.5 + 1.14.5 diff --git a/java-buildpack.iml b/java-buildpack.iml index f5598f319a..e20d8c5328 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -263,41 +263,36 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index a865911854..5cd5d1f0f1 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -74,7 +74,7 @@ def children(root, s = Set.new) end def parse(input) - input ? JSON.load(input) : {} + input ? JSON.parse(input) : {} end end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb index 7dd5f8251f..56477c0778 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb index 3752dd515c..465a170dee 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb index 4530c1a406..7fbce98257 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb index 1c5d2f61e4..f008018797 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb index 917a3fb3b6..e16343453c 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb index 72ffe5c461..1fc82969e8 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb index 25eea81828..ffc82b3970 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb index b4c5722a6b..d5f090d09d 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb index 829b247966..ebaef00952 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb index 252d4d0333..7bd4d19d75 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb index b00e379749..741b709f3a 100644 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb +++ b/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb @@ -32,8 +32,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb index acc5b04526..8ad5492058 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb @@ -30,8 +30,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb index 4f6d2324ff..6c306e185b 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb @@ -28,8 +28,7 @@ class TomcatInsightSupport < JavaBuildpack::Component::BaseComponent include JavaBuildpack::Container # (see JavaBuildpack::Component::BaseComponent#detect) - def detect - end + def detect; end # (see JavaBuildpack::Component::BaseComponent#compile) def compile @@ -37,8 +36,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end private diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index 765c77d4d8..90b2af251d 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -43,8 +43,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb index 52534ebb3e..b86d12e6d6 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb @@ -31,8 +31,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb index cd2ffee703..830bbc990d 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb @@ -35,8 +35,7 @@ def compile end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end protected diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index 762ab4a068..36915a6746 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -30,8 +30,7 @@ def detect end # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - end + def compile; end # (see JavaBuildpack::Component::BaseComponent#release) def release diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index dc638a5bd3..6b9e89ba6a 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -85,9 +85,10 @@ def port(java_opts, credentials) end def ssl_socket_factory(java_opts, credentials) - ssl = credentials['ssl'].to_b + return unless credentials['ssl'].to_b + java_opts.add_system_property 'introscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT', - 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory' if ssl + 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory' end end diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 919de6d24c..b798f1a6cd 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -30,8 +30,7 @@ def detect end # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - end + def compile; end # (see JavaBuildpack::Component::BaseComponent#release) def release diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index 5fc0531abf..b6d907eb91 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -50,10 +50,10 @@ def compile download_tar @droplet.copy_resources - unless @droplet.java_home.java_8_or_later? - $stderr.puts "\n WARNING: You are using #{@droplet.java_home.version}. Oracle has ended public " \ - "updates of Java 1.7 as of April 2015, possibly rendering your application vulnerable.\n\n" - end + return if @droplet.java_home.java_8_or_later? + + $stderr.puts "\n WARNING: You are using #{@droplet.java_home.version}. Oracle has ended public " \ + "updates of Java 1.7 as of April 2015, possibly rendering your application vulnerable.\n\n" end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 1415bc603b..121712800a 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -197,16 +197,21 @@ def client_authentication(http_options) client_authentication = JavaBuildpack::Util::ConfigurationUtils.load('cache')['client_authentication'] certificate_location = client_authentication['certificate_location'] - File.open(certificate_location) do |f| - http_options[:cert] = OpenSSL::X509::Certificate.new f.read - @logger.debug { "Adding client certificate from #{certificate_location}" } - end if certificate_location + if certificate_location + File.open(certificate_location) do |f| + http_options[:cert] = OpenSSL::X509::Certificate.new f.read + @logger.debug { "Adding client certificate from #{certificate_location}" } + end + end private_key_location = client_authentication['private_key_location'] + + return unless private_key_location + File.open(private_key_location) do |f| http_options[:key] = OpenSSL::PKey.read f.read, client_authentication['private_key_password'] @logger.debug { "Adding private key from #{private_key_location}" } - end if private_key_location + end end def compressed?(response) diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index b594033812..27b0c8df55 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -116,7 +116,7 @@ def load_configuration(file, user_provided, var_name, clean_nil_values, should_l if user_provided begin - user_provided_value = YAML.load(user_provided) + user_provided_value = YAML.safe_load(user_provided) configuration = merge_configuration(configuration, user_provided_value, var_name, should_log) rescue Psych::SyntaxError => ex raise "User configuration value in environment variable #{var_name} has invalid syntax: #{ex}" diff --git a/lib/java_buildpack/util/filtering_pathname.rb b/lib/java_buildpack/util/filtering_pathname.rb index a4a4e4849b..4ca55866c9 100644 --- a/lib/java_buildpack/util/filtering_pathname.rb +++ b/lib/java_buildpack/util/filtering_pathname.rb @@ -198,14 +198,14 @@ def filtered_pathname(pathname) def method_missing(method, *args) check_mutable if MUTATORS.member? method - if block_given? - result = delegate.send(method, *args) do |*values| - converted_values = values.map { |value| convert_if_necessary(value) }.compact - yield(*converted_values) unless converted_values.empty? - end - else - result = delegate.send(method, *args) - end + result = if block_given? + delegate.send(method, *args) do |*values| + converted_values = values.map { |value| convert_if_necessary(value) }.compact + yield(*converted_values) unless converted_values.empty? + end + else + delegate.send(method, *args) + end convert_result_if_necessary(result) end diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 41d4ad2678..3d8dc8bd97 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -165,7 +165,7 @@ def uris(configurations) def get_from_cache(configuration, index_configuration, uris) @cache.get(index_configuration[:uri]) do |f| - index = YAML.load f + index = YAML.safe_load f found_version = version(configuration, index) pin_version(configuration, found_version.to_s) if ENV['PINNED'].to_b diff --git a/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb b/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb index 2fad1c155c..a1a134493c 100644 --- a/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb +++ b/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb @@ -29,12 +29,10 @@ def detect end # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - end + def compile; end # (see JavaBuildpack::Component::BaseComponent#release) - def release - end + def release; end end diff --git a/spec/java_buildpack/buildpack_spec.rb b/spec/java_buildpack/buildpack_spec.rb index e3aed80d61..8c9e0b6e49 100644 --- a/spec/java_buildpack/buildpack_spec.rb +++ b/spec/java_buildpack/buildpack_spec.rb @@ -24,17 +24,19 @@ include_context 'application_helper' include_context 'logging_helper' - let(:stub_container1) { instance_double('StubContainer2', detect: nil, component_name: 'StubContainer1') } + let(:stub_container1) { instance_double('StubContainer1', detect: nil, component_name: 'StubContainer1') } - let(:stub_container2) { instance_double('StubContainer2', detect: nil, component_name: 'StubContainer2') } + let(:stub_container2) do + instance_double('StubContainer2', detect: nil, compile: nil, release: nil, component_name: 'StubContainer2') + end let(:stub_framework1) { instance_double('StubFramework1', detect: nil) } - let(:stub_framework2) { instance_double('StubFramework2', detect: nil) } + let(:stub_framework2) { instance_double('StubFramework2', detect: nil, compile: nil, release: nil) } let(:stub_jre1) { instance_double('StubJre1', detect: nil, component_name: 'StubJre1') } - let(:stub_jre2) { instance_double('StubJre2', detect: nil, component_name: 'StubJre2') } + let(:stub_jre2) { instance_double('StubJre2', detect: nil, compile: nil, release: nil, component_name: 'StubJre2') } let(:buildpack) do buildpack = nil @@ -104,11 +106,11 @@ allow(stub_jre1).to receive(:detect).and_return('stub-jre-1') allow(stub_container1).to receive(:compile) - expect(stub_container2).not_to receive(:compile) + expect(stub_container2).not_to have_received(:compile) allow(stub_framework1).to receive(:compile) - expect(stub_framework2).not_to receive(:compile) + expect(stub_framework2).not_to have_received(:compile) allow(stub_jre1).to receive(:compile) - expect(stub_jre2).not_to receive(:compile) + expect(stub_jre2).not_to have_received(:compile) buildpack.compile end @@ -119,11 +121,11 @@ allow(stub_jre1).to receive(:detect).and_return('stub-jre-1') allow(stub_container1).to receive(:release).and_return('test-command') - expect(stub_container2).not_to receive(:release) + expect(stub_container2).not_to have_received(:release) allow(stub_framework1).to receive(:release) - expect(stub_framework2).not_to receive(:release) + expect(stub_framework2).not_to have_received(:release) allow(stub_jre1).to receive(:release) - expect(stub_jre2).not_to receive(:release) + expect(stub_jre2).not_to have_received(:release) expect(buildpack.release) .to eq({ 'addons' => [], diff --git a/spec/java_buildpack/component/additional_libraries_spec.rb b/spec/java_buildpack/component/additional_libraries_spec.rb index d475d92516..8c68b06751 100644 --- a/spec/java_buildpack/component/additional_libraries_spec.rb +++ b/spec/java_buildpack/component/additional_libraries_spec.rb @@ -52,15 +52,15 @@ it 'symbolically links additional libraries' do additional_libraries.link_to app_dir - test_jar_1 = app_dir + 'test-jar-1.jar' - test_jar_2 = app_dir + 'test-jar-2.jar' - expect(test_jar_1).to exist - expect(test_jar_1).to be_symlink - expect(test_jar_1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(app_dir)) + test_jar1 = app_dir + 'test-jar-1.jar' + test_jar2 = app_dir + 'test-jar-2.jar' + expect(test_jar1).to exist + expect(test_jar1).to be_symlink + expect(test_jar1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(app_dir)) - expect(test_jar_2).to exist - expect(test_jar_2).to be_symlink - expect(test_jar_2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(app_dir)) + expect(test_jar2).to exist + expect(test_jar2).to be_symlink + expect(test_jar2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(app_dir)) end end diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index 4ee3c609ea..1c22c8aa43 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -61,15 +61,15 @@ lib = app_dir + 'lib' - test_jar_1 = lib + 'test-jar-1.jar' - test_jar_2 = lib + 'test-jar-2.jar' - expect(test_jar_1).to exist - expect(test_jar_1).to be_symlink - expect(test_jar_1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(lib)) - - expect(test_jar_2).to exist - expect(test_jar_2).to be_symlink - expect(test_jar_2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(lib)) + test_jar1 = lib + 'test-jar-1.jar' + test_jar2 = lib + 'test-jar-2.jar' + expect(test_jar1).to exist + expect(test_jar1).to be_symlink + expect(test_jar1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(lib)) + + expect(test_jar2).to exist + expect(test_jar2).to be_symlink + expect(test_jar2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(lib)) end context do diff --git a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb index 3afbfb6022..e7e2869e7d 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb @@ -153,15 +153,15 @@ web_inf_lib = app_dir + 'WEB-INF/lib' - test_jar_1 = web_inf_lib + 'test-jar-1.jar' - test_jar_2 = web_inf_lib + 'test-jar-2.jar' - expect(test_jar_1).to exist - expect(test_jar_1).to be_symlink - expect(test_jar_1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(web_inf_lib)) - - expect(test_jar_2).to exist - expect(test_jar_2).to be_symlink - expect(test_jar_2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(web_inf_lib)) + test_jar1 = web_inf_lib + 'test-jar-1.jar' + test_jar2 = web_inf_lib + 'test-jar-2.jar' + expect(test_jar1).to exist + expect(test_jar1).to be_symlink + expect(test_jar1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(web_inf_lib)) + + expect(test_jar2).to exist + expect(test_jar2).to be_symlink + expect(test_jar2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(web_inf_lib)) end end diff --git a/spec/java_buildpack/framework/debug_spec.rb b/spec/java_buildpack/framework/debug_spec.rb index 713dad0f3b..f3f6653e5b 100644 --- a/spec/java_buildpack/framework/debug_spec.rb +++ b/spec/java_buildpack/framework/debug_spec.rb @@ -32,12 +32,7 @@ expect(component.detect).to eq('debug=8000') end - it 'uses 8000 as the default port' do - component.release - expect(java_opts).to include('-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n') - end - - it 'does not suspend by default' do + it 'uses 8000 as the default port and does not suspend by default' do component.release expect(java_opts).to include('-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n') end diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 509c18b685..0d3b9e0479 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -72,7 +72,7 @@ .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original - expect(Net::HTTP).not_to receive(:Proxy).with('proxy', 9000, nil, nil) + expect(Net::HTTP).not_to have_received(:Proxy).with('proxy', 9000, nil, nil) expect { |b| download_cache.get uri, &b }.to yield_file_with_content(/foo-cached/) expect_complete_cache mutable_cache_root @@ -84,7 +84,7 @@ .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original - expect(Net::HTTP).not_to receive(:Proxy).with('proxy', 9000, nil, nil) + expect(Net::HTTP).not_to have_received(:Proxy).with('proxy', 9000, nil, nil) expect { |b| download_cache.get uri_credentials, &b }.to yield_file_with_content(/foo-cached/) expect_complete_cache mutable_cache_root diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index a1e6a674f2..47c4c33dca 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -89,17 +89,17 @@ it 'adds additional libraries to lib directory of a Play 2.0 dist application' do play_app.compile - lib_dir = app_dir + 'application-root/lib' - test_jar_1 = lib_dir + 'test-jar-1.jar' - test_jar_2 = lib_dir + 'test-jar-2.jar' + lib_dir = app_dir + 'application-root/lib' + test_jar1 = lib_dir + 'test-jar-1.jar' + test_jar2 = lib_dir + 'test-jar-2.jar' - expect(test_jar_1).to exist - expect(test_jar_1).to be_symlink - expect(test_jar_1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(lib_dir)) + expect(test_jar1).to exist + expect(test_jar1).to be_symlink + expect(test_jar1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(lib_dir)) - expect(test_jar_2).to exist - expect(test_jar_2).to be_symlink - expect(test_jar_2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(lib_dir)) + expect(test_jar2).to exist + expect(test_jar2).to be_symlink + expect(test_jar2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(lib_dir)) end it 'returns command' do diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index 1bc8d6f22b..cc7edea469 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -90,16 +90,16 @@ play_app.compile staged_dir = app_dir + 'staged' - test_jar_1 = staged_dir + 'test-jar-1.jar' - test_jar_2 = staged_dir + 'test-jar-2.jar' + test_jar1 = staged_dir + 'test-jar-1.jar' + test_jar2 = staged_dir + 'test-jar-2.jar' - expect(test_jar_1).to exist - expect(test_jar_1).to be_symlink - expect(test_jar_1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(staged_dir)) + expect(test_jar1).to exist + expect(test_jar1).to be_symlink + expect(test_jar1.readlink).to eq((additional_libs_directory + 'test-jar-1.jar').relative_path_from(staged_dir)) - expect(test_jar_2).to exist - expect(test_jar_2).to be_symlink - expect(test_jar_2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(staged_dir)) + expect(test_jar2).to exist + expect(test_jar2).to be_symlink + expect(test_jar2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(staged_dir)) end it 'returns command' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 013c1d8227..bb3b4d5a99 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,14 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -require 'simplecov' -SimpleCov.start do - add_filter 'spec' -end - -require 'codeclimate-test-reporter' -CodeClimate::TestReporter.start - require 'webmock/rspec' WebMock.disable_net_connect!(allow: 'codeclimate.com') From 8ecba51048191989b7fa7c2bf01e4f03a539f30b Mon Sep 17 00:00:00 2001 From: Christopher Frost Date: Mon, 12 Dec 2016 16:55:10 +0000 Subject: [PATCH 234/812] Implement Memory Calculator v3 Adds support for calling the new Memory calculator API and functionality for counting the class and groovy files in an application. [#137719997] --- .idea/.rakeTasks | 2 +- config/components.yml | 1 - config/open_jdk_jre.yml | 18 +--- config/oracle_jre.yml | 18 +--- config/zulu_jre.yml | 24 +---- java-buildpack.iml | 10 +-- lib/java_buildpack/framework/java_opts.rb | 13 +-- .../jre/open_jdk_like_memory_calculator.rb | 80 ++++++++--------- .../{.lib => BOOT-INF/lib}/.gitignore | 0 .../integration_valid/META-INF/MANIFEST.MF | 3 +- .../io/pivotal/SimpleJava.class} | 0 .../bat.class | 0 .../foo.class_with_suffix | 0 .../stub-library.jar | Bin 0 -> 828 bytes .../framework/java_opts_spec.rb | 56 ------------ .../open_jdk_like_memory_calculator_spec.rb | 82 +++++------------- spec/java_buildpack/jre/open_jdk_like_spec.rb | 32 ++++--- 17 files changed, 87 insertions(+), 252 deletions(-) rename spec/fixtures/integration_valid/{.lib => BOOT-INF/lib}/.gitignore (100%) rename spec/fixtures/{stub-memory-calculator => integration_valid/io/pivotal/SimpleJava.class} (100%) create mode 100644 spec/fixtures/jre_memory_calculator_application/bat.class create mode 100644 spec/fixtures/jre_memory_calculator_application/foo.class_with_suffix create mode 100644 spec/fixtures/jre_memory_calculator_application/stub-library.jar diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index 56aac576a4..8ce9d6bdd1 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/config/components.yml b/config/components.yml index 88024998f9..a280d45644 100644 --- a/config/components.yml +++ b/config/components.yml @@ -35,7 +35,6 @@ jres: # Frameworks are processed in order. Any Java Opts added by the JavaOpts framework will be specified in the start # command after any Java Opts added by previous frameworks. - frameworks: # - "JavaBuildpack::Framework::AppDynamicsAgent" - "JavaBuildpack::Framework::ContainerCertificateTrustStore" diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index cc0c19deca..e6e93a86e2 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -20,22 +20,6 @@ jre: version: 1.8.0_12+ repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" memory_calculator: - version: 2.+ + version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" stack_threads: 300 - memory_sizes: - heap: - metaspace: 64m.. - native: - permgen: 64m.. - stack: 228k.. - memory_heuristics: - heap: 65 - metaspace: 10 - native: 15 - permgen: 10 - stack: 10 - memory_initials: - heap: 100% - metaspace: 100% - permgen: 100% diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index 8d9cff7765..b2789671fc 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -23,22 +23,6 @@ jre: version: 1.8.0_12+ repository_root: "" memory_calculator: - version: 2.+ + version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" stack_threads: 300 - memory_sizes: - heap: - metaspace: 64m.. - native: - permgen: 64m.. - stack: 228k.. - memory_heuristics: - heap: 65 - metaspace: 10 - native: 15 - permgen: 10 - stack: 10 - memory_initials: - heap: 100% - metaspace: 100% - permgen: 100% diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 47e4b955f3..b220095228 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2016 the original author or authors. +# Copyright 2013-2017 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,22 +23,6 @@ jre: version: 1.8.0_12+ repository_root: "https://cdn.azul.com/zulu/bin" memory_calculator: - version: 2.+ - repository_root: ! '{default.repository.root}/memory-calculator/{platform}/{architecture}' - stack_threads: - memory_sizes: - heap: - metaspace: 64m.. - native: - permgen: 64m.. - stack: - memory_heuristics: - heap: 75 - metaspace: 10 - native: 10 - permgen: 10 - stack: 5 - memory_initials: - heap: 100% - metaspace: 100% - permgen: 100% + version: 3.+ + repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + stack_threads: 300 diff --git a/java-buildpack.iml b/java-buildpack.iml index e20d8c5328..913886a745 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -278,21 +278,21 @@ - + - - + + - + - + diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index efa15c433f..a70a56299b 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -31,13 +31,7 @@ def detect end # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - parsed_java_opts.each do |option| - if memory_option? option - raise "Java option '#{option}' configures a memory region. Use JRE configuration for this instead." - end - end - end + def compile; end # (see JavaBuildpack::Component::BaseComponent#release) def release @@ -54,11 +48,6 @@ def release private_constant :CONFIGURATION_PROPERTY, :ENVIRONMENT_PROPERTY, :ENVIRONMENT_VARIABLE - def memory_option?(option) - option =~ /-Xms/ || option =~ /-Xmx/ || option =~ /-XX:MaxMetaspaceSize/ || option =~ /-XX:MaxPermSize/ || - option =~ /-Xss/ || option =~ /-XX:MetaspaceSize/ || option =~ /-XX:PermSize/ - end - def parsed_java_opts parsed_java_opts = [] diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 642243728e..64458318d6 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -20,6 +20,7 @@ require 'java_buildpack/util/shell' require 'java_buildpack/util/qualify_path' require 'open3' +require 'tmpdir' module JavaBuildpack module Jre @@ -32,15 +33,19 @@ class OpenJDKLikeMemoryCalculator < JavaBuildpack::Component::VersionedDependenc def compile download(@version, @uri) do |file| FileUtils.mkdir_p memory_calculator.parent + if @version[0] < '2' unpack_calculator file else unpack_compressed_calculator file end + memory_calculator.chmod 0o755 - end - show_settings memory_calculation_string(Pathname.new(Dir.pwd)) + puts " Loaded Classes: #{class_count @configuration}, " \ + "Threads: #{stack_threads @configuration}, " \ + "JAVA_OPTS: '#{java_opts}'" + end end # Returns a fully qualified memory calculation command to be prepended to the buildpack's command sequence @@ -64,6 +69,24 @@ def supports? private + def actual_class_count(root) + (root + '**/*.class').glob.count + + (root + '**/*.groovy').glob.count + + (root + '**/*.jar').glob.inject(0) { |a, e| a + archive_class_count(e) } + end + + def archive_class_count(archive) + `unzip -l #{archive} | grep '\\(\\.class\\|\\.groovy\\)$' | wc -l`.to_i + end + + def class_count(configuration) + configuration['class_count'] || (0.2 * actual_class_count(@application.root)).ceil + 5500 + end + + def java_opts + ENV['JAVA_OPTS'] + end + def memory_calculator @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{@version}" end @@ -74,24 +97,22 @@ def memory_calculator_tar end def memory_calculation_string(relative_path) - "#{qualify_path memory_calculator, relative_path} -memorySizes=#{memory_sizes @configuration} " \ - "-memoryWeights=#{memory_weights @configuration} -memoryInitials=#{memory_initials @configuration}" \ - "#{stack_threads @configuration} -totMemory=$MEMORY_LIMIT" - end - - def memory_sizes(configuration) - memory_sizes = version_specific configuration['memory_sizes'] - memory_sizes.map { |k, v| "#{k}:#{v}" }.join(',') + memory_calculation_string = [qualify_path(memory_calculator, relative_path)] + memory_calculation_string << '-totMemory=$MEMORY_LIMIT' + memory_calculation_string << "-stackThreads=#{stack_threads @configuration}" + memory_calculation_string << "-loadedClasses=#{class_count @configuration}" + memory_calculation_string << "-poolType=#{pool_type}" + memory_calculation_string << "-vmOptions='#{java_opts}'" if java_opts + + memory_calculation_string.join(' ') end - def memory_weights(configuration) - memory_heuristics = version_specific configuration['memory_heuristics'] - memory_heuristics.map { |k, v| "#{k}:#{v}" }.join(',') + def pool_type + @droplet.java_home.java_8_or_later? ? 'metaspace' : 'permgen' end - def memory_initials(configuration) - memory_initials = version_specific configuration['memory_initials'] - memory_initials.map { |k, v| "#{k}:#{v}" }.join(',') + def stack_threads(configuration) + configuration['stack_threads'] end def unpack_calculator(file) @@ -103,33 +124,6 @@ def unpack_compressed_calculator(file) FileUtils.mv(memory_calculator_tar, memory_calculator) end - def stack_threads(configuration) - configuration['stack_threads'] ? " -stackThreads=#{configuration['stack_threads']}" : '' - end - - def version_specific(configuration) - if @droplet.java_home.java_8_or_later? - configuration.delete 'permgen' - else - configuration.delete 'metaspace' - end - - configuration - end - - def show_settings(*args) - Open3.popen3(*args) do |_stdin, stdout, stderr, wait_thr| - status = wait_thr.value - stderr_content = stderr.gets nil - stdout_content = stdout.gets nil - - puts " #{stderr_content}" if stderr_content - - raise unless status.success? - puts " Memory Settings: #{stdout_content}" - end - end - end end diff --git a/spec/fixtures/integration_valid/.lib/.gitignore b/spec/fixtures/integration_valid/BOOT-INF/lib/.gitignore similarity index 100% rename from spec/fixtures/integration_valid/.lib/.gitignore rename to spec/fixtures/integration_valid/BOOT-INF/lib/.gitignore diff --git a/spec/fixtures/integration_valid/META-INF/MANIFEST.MF b/spec/fixtures/integration_valid/META-INF/MANIFEST.MF index 562a9b4e98..e5be5e0001 100644 --- a/spec/fixtures/integration_valid/META-INF/MANIFEST.MF +++ b/spec/fixtures/integration_valid/META-INF/MANIFEST.MF @@ -1,4 +1,3 @@ Manifest-Version: 1.0 -Class-Path: . -Main-Class: com.gopivotal.SimpleJava +Main-Class: io.pivotal.SimpleJava diff --git a/spec/fixtures/stub-memory-calculator b/spec/fixtures/integration_valid/io/pivotal/SimpleJava.class similarity index 100% rename from spec/fixtures/stub-memory-calculator rename to spec/fixtures/integration_valid/io/pivotal/SimpleJava.class diff --git a/spec/fixtures/jre_memory_calculator_application/bat.class b/spec/fixtures/jre_memory_calculator_application/bat.class new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/jre_memory_calculator_application/foo.class_with_suffix b/spec/fixtures/jre_memory_calculator_application/foo.class_with_suffix new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/jre_memory_calculator_application/stub-library.jar b/spec/fixtures/jre_memory_calculator_application/stub-library.jar new file mode 100644 index 0000000000000000000000000000000000000000..2ef99768fce6160e8273ccc7b38b779296f209db GIT binary patch literal 828 zcmWIWW@Zs#;Nak3P)m06Vn70%3@i-3t|5-Po_=on|4uP5Ff#;rvvYt{FhP|C;M6Pv zQ~}rQ>*(j{<{BKL=j-;__snS@Z(Y5MyxzK6=gyqp9At3C_`%a6JuhD!Pv48Bt5`TA zUPvC1mXg%U_#v*U_I!z!#dC4dC*rEp7_Mf2D*9N&2zG^l;4&o_pdGG23~~h*0|U@y zGH71l1kx7IBHC|wW4vH6401s$TECqO@YDEqyP^=(;EszP< ziWEm66Sx>~hbY2?!$2ll_#(7o3t@!Tcj#J?!W&@*wh%{{p~Q%0eNrOU@JE=3Ed~(g ZC83*#6d$Z?Aa!g&I02|?8W1xu002`}mM#DQ literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index 42f179ff6e..b53ef21713 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -127,62 +127,6 @@ end end - context do - let(:configuration) { { 'java_opts' => '-Xms1024M' } } - - it 'raises an error if a -Xms is configured' do - expect { component.compile }.to raise_error(/-Xms/) - end - end - - context do - let(:configuration) { { 'java_opts' => '-Xmx1024M' } } - - it 'raises an error if a -Xmx is configured' do - expect { component.compile }.to raise_error(/-Xmx/) - end - end - - context do - let(:configuration) { { 'java_opts' => '-XX:MaxMetaspaceSize=128M' } } - - it 'raises an error if a -XX:MaxMetaspaceSize is configured' do - expect { component.compile }.to raise_error(/-XX:MaxMetaspaceSize/) - end - end - - context do - let(:configuration) { { 'java_opts' => '-XX:MetaspaceSize=128M' } } - - it 'raises an error if a -XX:MetaspaceSize is configured' do - expect { component.compile }.to raise_error(/-XX:MetaspaceSize/) - end - end - - context do - let(:configuration) { { 'java_opts' => '-XX:MaxPermSize=128M' } } - - it 'raises an error if a -XX:MaxPermSize is configured' do - expect { component.compile }.to raise_error(/-XX:MaxPermSize/) - end - end - - context do - let(:configuration) { { 'java_opts' => '-XX:PermSize=128M' } } - - it 'raises an error if a -XX:PermSize is configured' do - expect { component.compile }.to raise_error(/-XX:PermSize/) - end - end - - context do - let(:configuration) { { 'java_opts' => '-Xss1M' } } - - it 'raises an error if a -Xss is configured' do - expect { component.compile }.to raise_error(/-Xss/) - end - end - context do let(:configuration) { { 'from_environment' => true } } let(:environment) { { 'JAVA_OPTS' => '-Dalpha=bravo' } } diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index a0a8a77b11..6e4fdb2e3b 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -24,29 +24,15 @@ include_context 'component_helper' include JavaBuildpack::Util - let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } + let(:configuration) { { 'stack_threads' => '200' } } - let(:version_7) { VERSION_7 = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } + let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } let(:version_8) { VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } - let(:configuration) do - { 'memory_sizes' => { 'metaspace' => '64m..', - 'permgen' => '64m..' }, - 'memory_heuristics' => { 'heap' => '75', - 'metaspace' => '10', - 'permgen' => '10', - 'stack' => '5', - 'native' => '10' }, - 'memory_initials' => { 'heap' => '100%', - 'metaspace' => '100%', - 'permgen' => '100%' } } - end - it 'copies executable to bin directory', - cache_fixture: 'stub-memory-calculator' do + cache_fixture: 'stub-memory-calculator.tar.gz' do - java_home.version = version_7 allow(component).to receive(:show_settings) component.compile @@ -55,9 +41,8 @@ end it 'chmods executable to 0755', - cache_fixture: 'stub-memory-calculator' do + cache_fixture: 'stub-memory-calculator.tar.gz' do - java_home.version = version_7 allow(component).to receive(:show_settings) component.compile @@ -72,7 +57,6 @@ it 'copies executable to bin directory from a compressed archive', cache_fixture: 'stub-memory-calculator.tar.gz' do - java_home.version = version_7 allow(component).to receive(:show_settings) component.compile @@ -83,7 +67,6 @@ it 'chmods executable to 0755 from a compressed archive', cache_fixture: 'stub-memory-calculator.tar.gz' do - java_home.version = version_7 allow(component).to receive(:show_settings) component.compile @@ -93,61 +76,38 @@ end - it 'runs the memory calculator to sanity check', - cache_fixture: 'stub-memory-calculator' do - - java_home.version = version_7 - memory_calculator = qualify_path(sandbox + "bin/java-buildpack-memory-calculator-#{version}", Pathname.new(Dir.pwd)) - - allow(component).to receive(:show_settings).with("#{memory_calculator} -memorySizes=permgen:64m.. " \ - '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ - '-memoryInitials=heap:100%,permgen:100% ' \ - '-totMemory=$MEMORY_LIMIT') + it 'adds $CALCULATED_MEMORY to the JAVA_OPTS' do + component.release - component.compile + expect(java_opts).to include('$CALCULATED_MEMORY') end - it 'create memory calculation command for Java 7' do - java_home.version = version_7 - command = component.memory_calculation_command + it 'creates memory calculation command without vm options specified', + app_fixture: 'jre_memory_calculator_application' do - expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ - 'java-buildpack-memory-calculator-0.0.0 -memorySizes=permgen:64m.. ' \ - '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ - '-memoryInitials=heap:100%,permgen:100% ' \ - '-totMemory=$MEMORY_LIMIT)') - end - - it 'create memory calculation command for Java 8' do java_home.version = version_8 - command = component.memory_calculation_command + + command = component.memory_calculation_command expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ - 'java-buildpack-memory-calculator-0.0.0 -memorySizes=metaspace:64m.. ' \ - '-memoryWeights=heap:75,metaspace:10,stack:5,native:10 ' \ - '-memoryInitials=heap:100%,metaspace:100% ' \ - '-totMemory=$MEMORY_LIMIT)') + 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ + '-loadedClasses=5501 -poolType=metaspace)') end - it 'adds $CALCULATED_MEMORY to the JAVA_OPTS' do - component.release + context do - expect(java_opts).to include('$CALCULATED_MEMORY') - end + let(:environment) { { 'JAVA_OPTS' => '-Dalpha=bravo' } } - context do + it 'creates memory calculation command with vm options specified', + app_fixture: 'jre_memory_calculator_application' do - let(:configuration) { super().merge 'stack_threads' => '200' } + java_home.version = version_8 - it 'create memory calculation command with stack threads specified' do - java_home.version = version_7 - command = component.memory_calculation_command + command = component.memory_calculation_command expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ - 'java-buildpack-memory-calculator-0.0.0 -memorySizes=permgen:64m.. ' \ - '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ - '-memoryInitials=heap:100%,permgen:100% ' \ - '-stackThreads=200 -totMemory=$MEMORY_LIMIT)') + 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ + '-loadedClasses=5501 -poolType=metaspace -vmOptions=\'-Dalpha=bravo\')') end end diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index 66f5297218..46dbae01b3 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -31,6 +31,8 @@ let(:version_7) { VERSION_7 = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } + let(:version_8) { VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } + let(:configuration) do { 'jre' => jre_configuration, 'memory_calculator' => memory_calculator_configuration } @@ -38,18 +40,7 @@ let(:jre_configuration) { instance_double('jre_configuration') } - let(:memory_calculator_configuration) do - { 'memory_sizes' => { 'metaspace' => '64m..', - 'permgen' => '64m..' }, - 'memory_heuristics' => { 'heap' => '75', - 'metaspace' => '10', - 'permgen' => '10', - 'stack' => '5', - 'native' => '10' }, - 'memory_initials' => { 'heap' => '100%', - 'metaspace' => '100%', - 'permgen' => '100%' } } - end + let(:memory_calculator_configuration) { { 'stack_threads' => '200' } } it 'always supports' do expect(component.supports?).to be @@ -66,13 +57,20 @@ component.sub_components context end - it 'returns command' do + it 'returns command for Java 7' do java_home.version = version_7 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ - 'java-buildpack-memory-calculator-0.0.0 -memorySizes=permgen:64m.. ' \ - '-memoryWeights=heap:75,permgen:10,stack:5,native:10 ' \ - '-memoryInitials=heap:100%,permgen:100% ' \ - '-totMemory=$MEMORY_LIMIT)') + 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ + ' -stackThreads=200 -loadedClasses=5500 -poolType=permgen)') + + end + + it 'returns command for Java 8' do + java_home.version = version_8 + expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ + 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ + ' -stackThreads=200 -loadedClasses=5500 -poolType=metaspace)') + end end From de19e32127f077d883f9b591a5a3f699aa837f77 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 6 Mar 2017 13:23:44 -0800 Subject: [PATCH 235/812] Include More Classes In Calculation Previously, only the classes actually in the application were candidates for use when calculating the total number of classes in the application. There was a fixed 5500 class offset to account for the un-evaluated JRE. However, there were problems when downstream buildpacks added large servers to the application (e.g. Wildfly) and 10s of thousands classes were not accounted for. This change enumerates the number of classes in the _entire_ droplet, including the JRE, and removes the constant offset. --- .idea/dictionaries/bhale.xml | 1 + .../jre/open_jdk_like_memory_calculator.rb | 11 ++++++++--- spec/fixtures/additional_libs/test-jar-1.jar | Bin 0 -> 342 bytes spec/fixtures/additional_libs/test-jar-2.jar | Bin 0 -> 342 bytes .../jre/open_jdk_like_memory_calculator_spec.rb | 4 ++-- spec/java_buildpack/jre/open_jdk_like_spec.rb | 4 ++-- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 0b69007560..f8de0d3fa2 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -21,6 +21,7 @@ dirname distapplication dnewrelic + dotmatch enterprisemanager etag extname diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 64458318d6..50f40422cb 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -17,6 +17,7 @@ require 'fileutils' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/jre' +require 'java_buildpack/util/filtering_pathname' require 'java_buildpack/util/shell' require 'java_buildpack/util/qualify_path' require 'open3' @@ -72,15 +73,19 @@ def supports? def actual_class_count(root) (root + '**/*.class').glob.count + (root + '**/*.groovy').glob.count + - (root + '**/*.jar').glob.inject(0) { |a, e| a + archive_class_count(e) } + (root + '**/*.jar').glob(File::FNM_DOTMATCH).inject(0) { |a, e| a + archive_class_count(e) } end def archive_class_count(archive) - `unzip -l #{archive} | grep '\\(\\.class\\|\\.groovy\\)$' | wc -l`.to_i + a = `unzip -l #{archive} | grep '\\(\\.class\\|\\.groovy\\)$' | wc -l`.to_i + $stderr.puts "#{archive}: #{a}" + + a end def class_count(configuration) - configuration['class_count'] || (0.2 * actual_class_count(@application.root)).ceil + 5500 + root = JavaBuildpack::Util::FilteringPathname.new(@droplet.root, ->(_) { true }, true) + configuration['class_count'] || (0.2 * actual_class_count(root)).ceil end def java_opts diff --git a/spec/fixtures/additional_libs/test-jar-1.jar b/spec/fixtures/additional_libs/test-jar-1.jar index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8b0d26227e984fa173f2a8264b5ef31ea88debb1 100644 GIT binary patch literal 342 zcmWIWW@Zs#;Nak32+T_JVn70%3@i-3t|5-Po_=on|4uP5Ff#;rvvYt{FhP|C;M6Pv zQ~}rQ>*(j{<{BKL=j-;__snS@Z(Y5MyxzK6=gyqp9At3C_`%a6JuhD!Pv48Bt5`TA zUPvC1mXg%U_#v*U_I!z!#dC4dC*rEp7_Mf2D*9N&2zG^l;4&o_pdGG29N^8!B*K8| u3788(okQWfZ7RZEaMe*(j{<{BKL=j-;__snS@Z(Y5MyxzK6=gyqp9At3C_`%a6JuhD!Pv48Bt5`TA zUPvC1mXg%U_#v*U_I!z!#dC4dC*rEp7_Mf2D*9N&2zG^l;4&o_pdGG29N^8!B*K8| u3788(okQWfZ7RZEaMe Date: Mon, 6 Mar 2017 14:51:35 -0800 Subject: [PATCH 236/812] Polishing --- lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 50f40422cb..daf7607d4d 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -77,10 +77,7 @@ def actual_class_count(root) end def archive_class_count(archive) - a = `unzip -l #{archive} | grep '\\(\\.class\\|\\.groovy\\)$' | wc -l`.to_i - $stderr.puts "#{archive}: #{a}" - - a + `unzip -l #{archive} | grep '\\(\\.class\\|\\.groovy\\)$' | wc -l`.to_i end def class_count(configuration) From 5c27866b8395bb481b90317f33df1ad00e4d4855 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 6 Mar 2017 15:07:50 -0800 Subject: [PATCH 237/812] Further tweaking memory calculator This change updates the calculation about how many classes are loaded versus exist. Previously it was 0.2, but I've now seen "typical" applications where that is higher. This change updates it for more wide-spread testing. --- lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index daf7607d4d..557d0b5b8b 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -82,7 +82,7 @@ def archive_class_count(archive) def class_count(configuration) root = JavaBuildpack::Util::FilteringPathname.new(@droplet.root, ->(_) { true }, true) - configuration['class_count'] || (0.2 * actual_class_count(root)).ceil + configuration['class_count'] || (0.35 * actual_class_count(root)).ceil end def java_opts From a914fd660aaf63c62478d430fc0b8a4bc35b0fcb Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 6 Mar 2017 15:13:33 -0800 Subject: [PATCH 238/812] Polishing --- .../jre/open_jdk_like_memory_calculator_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 885e1cf19a..832933e634 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -91,7 +91,7 @@ expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ - '-loadedClasses=1 -poolType=metaspace)') + '-loadedClasses=2 -poolType=metaspace)') end context do @@ -107,7 +107,7 @@ expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ - '-loadedClasses=1 -poolType=metaspace -vmOptions=\'-Dalpha=bravo\')') + '-loadedClasses=2 -poolType=metaspace -vmOptions=\'-Dalpha=bravo\')') end end From 03fccb8d5671d3988f98b9226a65314dc5afa771 Mon Sep 17 00:00:00 2001 From: Glyn Normington Date: Mon, 15 Aug 2016 11:38:52 +0100 Subject: [PATCH 239/812] Use jvmkill agent instead of killjava script The jvmkill agent parameters are hard-coded so that the JVM is killed on the first OOM. A memory histogram will be printed once the jvmkill agent dependency is upgraded, but this agent parameter is ignored. For background, see: * https://github.com/cloudfoundry/java-buildpack/issues/161 * https://github.com/cloudfoundry/java-buildpack/pull/246 [#114796351] --- README.md | 2 + config/open_jdk_jre.yml | 3 + config/oracle_jre.yml | 3 + config/zulu_jre.yml | 3 + docs/debugging-the-buildpack.md | 5 +- lib/java_buildpack/jre/jvmkill_agent.rb | 58 +++++++++++++++++++ lib/java_buildpack/jre/open_jdk_like.rb | 4 +- lib/java_buildpack/jre/open_jdk_like_jre.rb | 7 --- resources/open_jdk_jre/bin/killjava.sh | 50 ---------------- resources/oracle_jre/bin/killjava.sh | 50 ---------------- resources/zulu_jre/bin/killjava.sh | 50 ---------------- spec/fixtures/stub-jvmkill-agent | 0 spec/java_buildpack/jre/jvmkill_agent_spec.rb | 46 +++++++++++++++ .../jre/open_jdk_like_jre_spec.rb | 21 ------- spec/java_buildpack/jre/open_jdk_like_spec.rb | 7 ++- 15 files changed, 126 insertions(+), 183 deletions(-) create mode 100644 lib/java_buildpack/jre/jvmkill_agent.rb delete mode 100755 resources/open_jdk_jre/bin/killjava.sh delete mode 100755 resources/oracle_jre/bin/killjava.sh delete mode 100755 resources/zulu_jre/bin/killjava.sh create mode 100644 spec/fixtures/stub-jvmkill-agent create mode 100644 spec/java_buildpack/jre/jvmkill_agent_spec.rb diff --git a/README.md b/README.md index 0a2e76763e..cf55ec8195 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,10 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Buildpack Modes](docs/buildpack-modes.md) * Related Projects * [Java Buildpack Dependency Builder](https://github.com/cloudfoundry/java-buildpack-dependency-builder) + * [Java Buildpack Memory Calculator](https://github.com/cloudfoundry/java-buildpack-memory-calculator) * [Java Test Applications](https://github.com/cloudfoundry/java-test-applications) * [Java Buildpack System Tests](https://github.com/cloudfoundry/java-buildpack-system-test) + * [jvmkill](https://github.com/cloudfoundry/jvmkill) ## Building Packages The buildpack can be packaged up so that it can be uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used. diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index e6e93a86e2..4d4c70fd76 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -19,6 +19,9 @@ jre: version: 1.8.0_12+ repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" +jvmkill_agent: + version: 1.+ + repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index b2789671fc..22745d3f12 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -22,6 +22,9 @@ jre: version: 1.8.0_12+ repository_root: "" +jvmkill_agent: + version: 1.+ + repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index b220095228..bfce055712 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -22,6 +22,9 @@ jre: version: 1.8.0_12+ repository_root: "https://cdn.azul.com/zulu/bin" +jvmkill_agent: + version: 1.+ + repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" diff --git a/docs/debugging-the-buildpack.md b/docs/debugging-the-buildpack.md index 354d351a6f..a3982e77ae 100644 --- a/docs/debugging-the-buildpack.md +++ b/docs/debugging-the-buildpack.md @@ -75,8 +75,7 @@ addons: [] config_vars: {} default_process_types: web: JAVA_HOME=$PWD/.java-buildpack/open_jdk_jre JAVA_OPTS="-Djava.io.tmpdir=$TMPDIR - -XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh -Xmx382293K - -Xms382293K -XX:MaxPermSize=64M -XX:PermSize=64M -Xss995K -Dalpha=bravo -Dhttp.port=$PORT" + -Xmx382293K -Xms382293K -XX:MaxPermSize=64M -XX:PermSize=64M -Xss995K -Dalpha=bravo -Dhttp.port=$PORT" $PWD/.java-buildpack/tomcat/bin/catalina.sh run ``` @@ -112,7 +111,7 @@ $ $BUILDPACK_ROOT/bin/compile . $TMPDIR -----> Downloading Spring Auto Reconfiguration 1.4.0_RELEASE from https://java-buildpack.cloudfoundry.org/auto-reconfiguration/auto-reconfiguration-1.4.0_RELEASE.jar (found in cache) $ $BUILDPACK_ROOT/bin/release . | ruby -e "require \"yaml\"; puts YAML.load(STDIN.read)[\"default_process_types\"][\"web\"]" -PATH=$PWD/.java-buildpack/open_jdk_jre/bin:$PATH JAVA_HOME=$PWD/.java-buildpack/open_jdk_jre $PWD/play-application-1.0.0.BUILD-SNAPSHOT/bin/play-application -J-Djava.io.tmpdir=$TMPDIR -J-XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh -J-XX:MaxPermSize=64M -J-XX:PermSize=64M -J-javaagent:$PWD/.java-buildpack/app_dynamics_agent/javaagent.jar -J-Dappdynamics.agent.applicationName='' -J-Dappdynamics.agent.tierName='Cloud Foundry' -J-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : '.*instance_id[": ]*"\([a-z0-9]\+\)".*') -J-Dappdynamics.agent.accountAccessKey=[REDACTED] -J-Dappdynamics.agent.accountName=[REDACTED] -J-Dappdynamics.controller.hostName=[REDACTED] -J-Dappdynamics.controller.port=443 -J-Dappdynamics.controller.ssl.enabled=true -J-Dhttp.port=$PORT +PATH=$PWD/.java-buildpack/open_jdk_jre/bin:$PATH JAVA_HOME=$PWD/.java-buildpack/open_jdk_jre $PWD/play-application-1.0.0.BUILD-SNAPSHOT/bin/play-application -J-Djava.io.tmpdir=$TMPDIR -J-XX:MaxPermSize=64M -J-XX:PermSize=64M -J-javaagent:$PWD/.java-buildpack/app_dynamics_agent/javaagent.jar -J-Dappdynamics.agent.applicationName='' -J-Dappdynamics.agent.tierName='Cloud Foundry' -J-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : '.*instance_id[": ]*"\([a-z0-9]\+\)".*') -J-Dappdynamics.agent.accountAccessKey=[REDACTED] -J-Dappdynamics.agent.accountName=[REDACTED] -J-Dappdynamics.controller.hostName=[REDACTED] -J-Dappdynamics.controller.port=443 -J-Dappdynamics.controller.ssl.enabled=true -J-Dhttp.port=$PORT ``` You can trigger different behaviour in the buildpack by setting the `VCAP_SERVICES` environment variable. For example, to fake the binding of a service. diff --git a/lib/java_buildpack/jre/jvmkill_agent.rb b/lib/java_buildpack/jre/jvmkill_agent.rb new file mode 100644 index 0000000000..127bc666eb --- /dev/null +++ b/lib/java_buildpack/jre/jvmkill_agent.rb @@ -0,0 +1,58 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/jre' + +module JavaBuildpack + module Jre + + # Encapsulates the detect, compile, and release functionality for the jvmkill agent + class JvmkillAgent < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download(@version, @uri) do |file| + FileUtils.mkdir_p jvmkill_agent.parent + FileUtils.cp(file.path, jvmkill_agent) + jvmkill_agent.chmod 0o755 + end + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts.add_agentpath_with_props(jvmkill_agent, 'printHeapHistogram' => '1') + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + private + + def jvmkill_agent + @droplet.sandbox + "bin/jvmkill-#{@version}" + end + + end + + end +end diff --git a/lib/java_buildpack/jre/open_jdk_like.rb b/lib/java_buildpack/jre/open_jdk_like.rb index a8b48a3468..1c30d6bc05 100644 --- a/lib/java_buildpack/jre/open_jdk_like.rb +++ b/lib/java_buildpack/jre/open_jdk_like.rb @@ -18,6 +18,7 @@ require 'java_buildpack/jre' require 'java_buildpack/jre/open_jdk_like_jre' require 'java_buildpack/jre/open_jdk_like_memory_calculator' +require 'java_buildpack/jre/jvmkill_agent' module JavaBuildpack module Jre @@ -37,7 +38,8 @@ def sub_components(context) [ OpenJDKLikeJre.new(sub_configuration_context(context, 'jre') .merge(component_name: self.class.to_s.space_case)), - OpenJDKLikeMemoryCalculator.new(sub_configuration_context(context, 'memory_calculator')) + OpenJDKLikeMemoryCalculator.new(sub_configuration_context(context, 'memory_calculator')), + JvmkillAgent.new(sub_configuration_context(context, 'jvmkill_agent')) ] end diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index b6d907eb91..7c0947a5f9 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -61,13 +61,6 @@ def release @droplet .java_opts .add_system_property('java.io.tmpdir', '$TMPDIR') - .add_option('-XX:OnOutOfMemoryError', killjava) - end - - private - - def killjava - @droplet.sandbox + 'bin/killjava.sh' end end diff --git a/resources/open_jdk_jre/bin/killjava.sh b/resources/open_jdk_jre/bin/killjava.sh deleted file mode 100755 index 106730238f..0000000000 --- a/resources/open_jdk_jre/bin/killjava.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Kill script for use as the parameter of OpenJDK's -XX:OnOutOfMemoryError - -set -e - -echo " -Process Status (Before) -======================= -$(ps -ef) - -ulimit (Before) -=============== -$(ulimit -a) - -Free Disk Space (Before) -======================== -$(df -h) -" - -pkill -9 -f .*-XX:OnOutOfMemoryError=.*killjava.* - -echo " -Process Status (After) -====================== -$(ps -ef) - -ulimit (After) -============== -$(ulimit -a) - -Free Disk Space (After) -======================= -$(df -h) -" diff --git a/resources/oracle_jre/bin/killjava.sh b/resources/oracle_jre/bin/killjava.sh deleted file mode 100755 index 106730238f..0000000000 --- a/resources/oracle_jre/bin/killjava.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Kill script for use as the parameter of OpenJDK's -XX:OnOutOfMemoryError - -set -e - -echo " -Process Status (Before) -======================= -$(ps -ef) - -ulimit (Before) -=============== -$(ulimit -a) - -Free Disk Space (Before) -======================== -$(df -h) -" - -pkill -9 -f .*-XX:OnOutOfMemoryError=.*killjava.* - -echo " -Process Status (After) -====================== -$(ps -ef) - -ulimit (After) -============== -$(ulimit -a) - -Free Disk Space (After) -======================= -$(df -h) -" diff --git a/resources/zulu_jre/bin/killjava.sh b/resources/zulu_jre/bin/killjava.sh deleted file mode 100755 index 5a25454560..0000000000 --- a/resources/zulu_jre/bin/killjava.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright (c) 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Kill script for use as the parameter of OpenJDK's -XX:OnOutOfMemoryError - -set -e - -echo " -Process Status (Before) -======================= -$(ps -ef) - -ulimit (Before) -=============== -$(ulimit -a) - -Free Disk Space (Before) -======================== -$(df -h) -" - -pkill -9 -f .*-XX:OnOutOfMemoryError=.*killjava.* - -echo " -Process Status (After) -====================== -$(ps -ef) - -ulimit (After) -============== -$(ulimit -a) - -Free Disk Space (After) -======================= -$(df -h) -" diff --git a/spec/fixtures/stub-jvmkill-agent b/spec/fixtures/stub-jvmkill-agent new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/jre/jvmkill_agent_spec.rb b/spec/java_buildpack/jre/jvmkill_agent_spec.rb new file mode 100644 index 0000000000..5525e41ae9 --- /dev/null +++ b/spec/java_buildpack/jre/jvmkill_agent_spec.rb @@ -0,0 +1,46 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/jre/jvmkill_agent' + +describe JavaBuildpack::Jre::JvmkillAgent do + include_context 'component_helper' + + it 'copies executable to bin directory', + cache_fixture: 'stub-jvmkill-agent' do + + component.compile + + expect(sandbox + "bin/jvmkill-#{version}").to exist + end + + it 'chmods executable to 0755', + cache_fixture: 'stub-jvmkill-agent' do + + component.compile + + expect(File.stat(sandbox + "bin/jvmkill-#{version}").mode).to eq(0o100755) + end + + it 'adds agent parameters to the JAVA_OPTS' do + component.release + + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jvmkill_agent/bin/jvmkill-0.0.0=printHeapHistogram=1') + end + +end diff --git a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index 6c4252174b..ea20bac8e2 100644 --- a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -43,13 +43,6 @@ expect(java_home.root).to eq(sandbox) end - it 'adds OnOutOfMemoryError to java_opts' do - component.detect - component.release - - expect(java_opts).to include('-XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_like_jre/bin/killjava.sh') - end - it 'adds java.io.tmpdir to java_opts' do component.detect component.release @@ -57,18 +50,4 @@ expect(java_opts).to include('-Djava.io.tmpdir=$TMPDIR') end - context do - - let(:component_id) { 'open_jdk_jre' } - - it 'places the killjava script (with appropriately substituted content) in the bin directory', - cache_fixture: 'stub-java.tar.gz' do - - component.detect - component.compile - - expect(sandbox + 'bin/killjava.sh').to exist - end - end - end diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index 2940f204fb..702b1cd0c3 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -35,11 +35,14 @@ let(:configuration) do { 'jre' => jre_configuration, - 'memory_calculator' => memory_calculator_configuration } + 'memory_calculator' => memory_calculator_configuration, + 'jvmkill_agent' => jvmkill_agent_configuration } end let(:jre_configuration) { instance_double('jre_configuration') } + let(:jvmkill_agent_configuration) { {} } + let(:memory_calculator_configuration) { { 'stack_threads' => '200' } } it 'always supports' do @@ -53,6 +56,8 @@ .to receive(:new).with(sub_configuration_context(jre_configuration).merge(component_name: 'Stub Open JDK Like')) allow(JavaBuildpack::Jre::OpenJDKLikeMemoryCalculator) .to receive(:new).with(sub_configuration_context(memory_calculator_configuration)) + allow(JavaBuildpack::Jre::JvmkillAgent) + .to receive(:new).with(sub_configuration_context(jvmkill_agent_configuration)) component.sub_components context end From a3441e7fd3cdc3401a3964d7a6bacee0a739a557 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 8 Mar 2017 15:37:10 -0800 Subject: [PATCH 240/812] Properly Relativize Path Previously, the path to the `java` binary in Play applications was not properly relative to the droplet's root. This change fixes that problem. [#380] --- lib/java_buildpack/util/play/base.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/util/play/base.rb b/lib/java_buildpack/util/play/base.rb index 4d9017fc3b..d24d7631f5 100644 --- a/lib/java_buildpack/util/play/base.rb +++ b/lib/java_buildpack/util/play/base.rb @@ -51,7 +51,8 @@ def jar?(pattern) # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts.add_system_property 'http.port', '$PORT' - @droplet.environment_variables.add_environment_variable 'PATH', "#{@droplet.java_home.root}/bin:$PATH" + @droplet.environment_variables + .add_environment_variable 'PATH', "#{qualify_path(@droplet.java_home.root, @droplet.root)}/bin:$PATH" [ @droplet.environment_variables.as_env_vars, From b9712b98b4b94261539304c51041ba2d671a8495 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 8 Mar 2017 15:43:34 -0800 Subject: [PATCH 241/812] Test Fixes --- lib/java_buildpack/util/play/base.rb | 2 +- spec/java_buildpack/util/play/post22_spec.rb | 4 ++-- spec/java_buildpack/util/play/pre22_dist_spec.rb | 8 ++++---- spec/java_buildpack/util/play/pre22_staged_spec.rb | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/java_buildpack/util/play/base.rb b/lib/java_buildpack/util/play/base.rb index d24d7631f5..6993b2098a 100644 --- a/lib/java_buildpack/util/play/base.rb +++ b/lib/java_buildpack/util/play/base.rb @@ -52,7 +52,7 @@ def jar?(pattern) def release @droplet.java_opts.add_system_property 'http.port', '$PORT' @droplet.environment_variables - .add_environment_variable 'PATH', "#{qualify_path(@droplet.java_home.root, @droplet.root)}/bin:$PATH" + .add_environment_variable 'PATH', "#{qualify_path(@droplet.java_home.root, @droplet.root)}/bin:$PATH" [ @droplet.environment_variables.as_env_vars, diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index 3e14c7ca72..eb12924ba6 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -47,8 +47,8 @@ end it 'returns command' do - expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ - 'exec $PWD/bin/play-application -Jtest-opt-2 -Jtest-opt-1 -J-Dhttp.port=$PORT') + expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ + "#{java_home.as_env_var} exec $PWD/bin/play-application -Jtest-opt-2 -Jtest-opt-1 -J-Dhttp.port=$PORT") end context do diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index 47c4c33dca..1c8a8c1936 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -103,8 +103,8 @@ end it 'returns command' do - expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ - 'exec $PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') + expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ + "#{java_home.as_env_var} exec $PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT") end end @@ -124,8 +124,8 @@ end it 'returns command' do - expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ - 'exec $PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') + expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ + "#{java_home.as_env_var} exec $PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT") end end diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index cc7edea469..7d24e5bd7d 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -103,8 +103,8 @@ end it 'returns command' do - expect(play_app.release).to eq("test-var-2 test-var-1 PATH=#{java_home.root}/bin:$PATH #{java_home.as_env_var} " \ - 'exec $PWD/start test-opt-2 test-opt-1 -Dhttp.port=$PORT') + expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ + "#{java_home.as_env_var} exec $PWD/start test-opt-2 test-opt-1 -Dhttp.port=$PORT") end end From d5f9f2a8b8d3d29f50ce2cf2e8d232799ff198d2 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 9 Mar 2017 10:14:11 -0800 Subject: [PATCH 242/812] Update to Tomcat 8.5 This change updates the default version of Tomcat to 8.5.x. [resolves #394] --- config/tomcat.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index c5ce81ec24..142eb6cc5b 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -16,13 +16,13 @@ # Configuration for the Tomcat container --- tomcat: - version: 8.0.+ + version: 8.5.+ repository_root: "{default.repository.root}/tomcat" - context_path: + context_path: external_configuration_enabled: false external_configuration: version: 1.+ - repository_root: + repository_root: lifecycle_support: version: 2.+ repository_root: "{default.repository.root}/tomcat-lifecycle-support" From 56022e0bdfe2d14d692a62b8fe0fb9464c0195a9 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 9 Mar 2017 10:42:15 -0800 Subject: [PATCH 243/812] Disable JRebel Framework Due to licensing restrictions the JRebel framework is being disabled in the buildpack. Customers that would like to continue using it can re-enable the dependency in a fork. [resolves #395] --- config/components.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/components.yml b/config/components.yml index 88024998f9..f4b92ce5b1 100644 --- a/config/components.yml +++ b/config/components.yml @@ -45,7 +45,7 @@ frameworks: - "JavaBuildpack::Framework::DynatraceOneAgent" # - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::Jmx" - - "JavaBuildpack::Framework::JrebelAgent" +# - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::LunaSecurityProvider" - "JavaBuildpack::Framework::DyadicEkmSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" From 72ab6a07cbd136f2bf469ae02a112c93efede989 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 9 Mar 2017 11:10:39 -0800 Subject: [PATCH 244/812] Remove GemFire Due to licensing restrictions, the change removes the GemFire Session Replication support for the buildpack. [resolves #396] --- config/tomcat.yml | 38 +--- docs/container-tomcat.md | 16 -- java-buildpack.iml | 10 +- lib/java_buildpack/container/tomcat.rb | 2 - .../container/tomcat/gemfire/gemfire.rb | 52 ----- .../tomcat/gemfire/gemfire_log4j_api.rb | 52 ----- .../tomcat/gemfire/gemfire_log4j_core.rb | 52 ----- .../tomcat/gemfire/gemfire_log4j_jcl.rb | 52 ----- .../tomcat/gemfire/gemfire_log4j_jul.rb | 52 ----- .../gemfire/gemfire_log4j_slf4j_impl.rb | 52 ----- .../tomcat/gemfire/gemfire_logging.rb | 52 ----- .../tomcat/gemfire/gemfire_logging_api.rb | 52 ----- .../tomcat/gemfire/gemfire_modules.rb | 52 ----- .../tomcat/gemfire/gemfire_modules_tomcat7.rb | 52 ----- .../tomcat/gemfire/gemfire_security.rb | 52 ----- .../container/tomcat/tomcat_gemfire_store.rb | 191 ------------------ ...omcat_gemfire_store_cache_client_after.xml | 8 - ...ner_tomcat_gemfire_store_context_after.xml | 19 -- ...iner_tomcat_gemfire_store_server_after.xml | 29 --- .../tomcat/gemfire/gemfire_log4j_api_spec.rb | 42 ---- .../tomcat/gemfire/gemfire_log4j_core_spec.rb | 42 ---- .../tomcat/gemfire/gemfire_log4j_jcl_spec.rb | 42 ---- .../tomcat/gemfire/gemfire_log4j_jul_spec.rb | 42 ---- .../gemfire/gemfire_log4j_slf4j_impl_spec.rb | 42 ---- .../gemfire/gemfire_logging_api_spec.rb | 42 ---- .../tomcat/gemfire/gemfire_logging_spec.rb | 42 ---- .../tomcat/gemfire/gemfire_modules_spec.rb | 42 ---- .../gemfire/gemfire_modules_tomcat7_spec.rb | 42 ---- .../tomcat/gemfire/gemfire_security_spec.rb | 42 ---- .../container/tomcat/gemfire/gemfire_spec.rb | 42 ---- .../tomcat/tomcat_gemfire_store_spec.rb | 138 ------------- 31 files changed, 7 insertions(+), 1478 deletions(-) delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb delete mode 100644 lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb delete mode 100644 lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb delete mode 100644 spec/fixtures/container_tomcat_gemfire_store_cache_client_after.xml delete mode 100644 spec/fixtures/container_tomcat_gemfire_store_context_after.xml delete mode 100644 spec/fixtures/container_tomcat_gemfire_store_server_after.xml delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_logging_api_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_logging_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_modules_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_security_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/gemfire/gemfire_spec.rb delete mode 100644 spec/java_buildpack/container/tomcat/tomcat_gemfire_store_spec.rb diff --git a/config/tomcat.yml b/config/tomcat.yml index c5ce81ec24..17ef612d62 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -18,11 +18,11 @@ tomcat: version: 8.0.+ repository_root: "{default.repository.root}/tomcat" - context_path: + context_path: external_configuration_enabled: false external_configuration: version: 1.+ - repository_root: + repository_root: lifecycle_support: version: 2.+ repository_root: "{default.repository.root}/tomcat-lifecycle-support" @@ -39,37 +39,3 @@ redis_store: database: 0 timeout: 2000 connection_pool_size: 2 -gemfire_store: - gemfire: - version: 8.+ - repository_root: "{default.repository.root}/gem-fire" - gemfire_modules: - version: 8.+ - repository_root: "{default.repository.root}/gem-fire-modules" - gemfire_modules_tomcat7: - version: 8.+ - repository_root: "{default.repository.root}/gem-fire-modules-tomcat7" - gemfire_security: - version: 8.+ - repository_root: "{default.repository.root}/gem-fire-security" - gemfire_logging: - version: 1.7.7 - repository_root: "{default.repository.root}/slf4j-jdk14" - gemfire_logging_api: - version: 1.7.7 - repository_root: "{default.repository.root}/slf4j-api" - gemfire_log4j_api: - version: 2.1.0 - repository_root: "{default.repository.root}/log4j-api" - gemfire_log4j_core: - version: 2.1.0 - repository_root: "{default.repository.root}/log4j-core" - gemfire_log4j_jcl: - version: 2.1.0 - repository_root: "{default.repository.root}/log4j-jcl" - gemfire_log4j_jul: - version: 2.1.0 - repository_root: "{default.repository.root}/log4j-jul" - gemfire_log4j_slf4j_impl: - version: 2.1.0 - repository_root: "{default.repository.root}/log4j-slf4j-impl" diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index 117009af46..0808db831e 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -25,18 +25,6 @@ The container can be configured by modifying the [`config/tomcat.yml`][] file in | `access_logging_support.repository_root` | The URL of the Tomcat Access Logging Support repository index ([details][repositories]). | `access_logging_support.version` | The version of Tomcat Access Logging Support to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/tomcat-access-logging-support/index.yml). | `access_logging_support.access_logging` | Set to `enabled` to turn on the access logging support. Default is `disabled`. -| `gemfire_store.gemfire.repository_root` | The URL of the GemFire repository index ([details][repositories]). -| `gemfire_store.gemfire.version` | The version of GemFire to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/gem-fire/index.yml). -| `gemfire_store.gemfire_logging.repository_root` | The URL of the GemFire Logging repository index ([details][repositories]). -| `gemfire_store.gemfire_logging.version` | The version of GemFire Logging to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/slf4j-jdk14/index.yml). -| `gemfire_store.gemfire_logging_api.repository_root` | The URL of the GemFire Logging API repository index ([details][repositories]). -| `gemfire_store.gemfire_logging_api.version` | The version of GemFire Logging API to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/slf4j-api/index.yml). -| `gemfire_store.gemfire_modules.repository_root` | The URL of the GemFire Modules repository index ([details][repositories]). -| `gemfire_store.gemfire_modules.version` | The version of GemFire Modules to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/gem-fire-modules/index.yml). -| `gemfire_store.gemfire_modules_tomcat7.repository_root` | The URL of the GemFire Modules Tomcat 7 repository index ([details][repositories]). -| `gemfire_store.gemfire_modules_tomcat7.version` | The version of GemFire Modules Tomcat 7 to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/gem-fire-modules-tomcat7/index.yml). -| `gemfire_store.gemfire_security.repository_root` | The URL of the GemFire Security repository index ([details][repositories]). -| `gemfire_store.gemfire_security.version` | The version of GemFire Security to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/gem-fire-security/index.yml). | `lifecycle_support.repository_root` | The URL of the Tomcat Lifecycle Support repository index ([details][repositories]). | `lifecycle_support.version` | The version of Tomcat Lifecycle Support to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/tomcat-lifecycle-support/index.yml). | `logging_support.repository_root` | The URL of the Tomcat Logging Support repository index ([details][repositories]). @@ -103,9 +91,6 @@ By default, the Tomcat instance is configured to store all Sessions and their da ### Redis To enable Redis-based session replication, simply bind a Redis service containing a name, label, or tag that has `session-replication` as a substring. -### GemFire -To enable GemFire-based session replication, simply bind a [Session State Caching (SSC) GemFire service][] containing a name, label, or tag that has `session_replication` as a substring. GemFire services intended to be used for session replication will automatically have a tag of 'session_replication'. - ## Managing Entropy Entropy from `/dev/random` is used heavily to create session ids, and on startup for initializing `SecureRandom`, which can then cause instances to fail to start in time (see the [Tomcat wiki]). Also, the entropy is shared so it's possible for a single app to starve the DEA of entropy and cause apps in other containers that make use of entropy to be blocked. If this is an issue then configuring `/dev/urandom` as an alternative source of entropy may help. It is unlikely, but possible, that this may cause some security issues which should be taken in to account. @@ -121,7 +106,6 @@ Additional supporting functionality can be found in the [`java-buildpack-support [Configuration and Extension]: ../README.md#configuration-and-extension [`config/tomcat.yml`]: ../config/tomcat.yml -[Session State Caching (SSC) GemFire service]: https://network.pivotal.io/products/p-ssc-gemfire [`java-buildpack-support`]: https://github.com/cloudfoundry/java-buildpack-support [repositories]: extending-repositories.md [Spring profiles]:http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/ diff --git a/java-buildpack.iml b/java-buildpack.iml index e20d8c5328..913886a745 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -278,21 +278,21 @@ - + - - + + - + - + diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index d1c154ba43..f4a1fbb703 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -23,7 +23,6 @@ require 'java_buildpack/container/tomcat/tomcat_logging_support' require 'java_buildpack/container/tomcat/tomcat_access_logging_support' require 'java_buildpack/container/tomcat/tomcat_redis_store' -require 'java_buildpack/container/tomcat/tomcat_gemfire_store' require 'java_buildpack/util/java_main_utils' module JavaBuildpack @@ -56,7 +55,6 @@ def sub_components(context) TomcatLoggingSupport.new(sub_configuration_context(context, 'logging_support')), TomcatAccessLoggingSupport.new(sub_configuration_context(context, 'access_logging_support')), TomcatRedisStore.new(sub_configuration_context(context, 'redis_store')), - TomcatGemfireStore.new(sub_configuration_context(context, 'gemfire_store')), TomcatInsightSupport.new(context) ] diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb deleted file mode 100644 index 56477c0778..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Tomcat Redis support. - class GemFire < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "gemfire-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb deleted file mode 100644 index 465a170dee..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Log4j API support. - class GemFireLog4jApi < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Log4j API') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "log4j-api-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb deleted file mode 100644 index 7fbce98257..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Log4j Core support. - class GemFireLog4jCore < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Log4j Core') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "log4j-core-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb deleted file mode 100644 index f008018797..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Log4j Jcl support. - class GemFireLog4jJcl < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Log4j Jcl') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "log4j-jcl-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb deleted file mode 100644 index e16343453c..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Log4j Jul support. - class GemFireLog4jJul < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Log4j Jul') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "log4j-jul-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb deleted file mode 100644 index 1fc82969e8..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Log4j Slf4j Impl support. - class GemFireLog4jSlf4jImpl < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Log4j Slf4j Impl') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "log4j-slf4j-impl-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb deleted file mode 100644 index ffc82b3970..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Tomcat Redis support. - class GemFireLogging < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Logging') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "slf4j-jdk14-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb deleted file mode 100644 index d5f090d09d..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_logging_api.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Tomcat Redis support. - class GemFireLoggingApi < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Logging API') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "slf4j-api-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb deleted file mode 100644 index ebaef00952..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Tomcat Redis support. - class GemFireModules < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Modules') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "gemfire-modules-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb deleted file mode 100644 index 7bd4d19d75..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Tomcat Redis support. - class GemFireModulesTomcat7 < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Modules Tomcat7') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "gemfire-modules-tomcat7-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb b/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb deleted file mode 100644 index 741b709f3a..0000000000 --- a/lib/java_buildpack/container/tomcat/gemfire/gemfire_security.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Tomcat Redis support. - class GemFireSecurity < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar(jar_name, tomcat_lib, 'GemFire Security') - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release; end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - true - end - - private - - def jar_name - "gemfire-security-#{@version}.jar" - end - end - - end -end diff --git a/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb b/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb deleted file mode 100644 index 271c2783a8..0000000000 --- a/lib/java_buildpack/container/tomcat/tomcat_gemfire_store.rb +++ /dev/null @@ -1,191 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/container' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/container/tomcat/gemfire/gemfire' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_api' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_core' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl' -require 'java_buildpack/container/tomcat/gemfire/gemfire_logging_api' -require 'java_buildpack/container/tomcat/gemfire/gemfire_logging' -require 'java_buildpack/container/tomcat/gemfire/gemfire_modules' -require 'java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7' -require 'java_buildpack/container/tomcat/gemfire/gemfire_security' -require 'java_buildpack/container/tomcat/tomcat_utils' -require 'java_buildpack/logging/logger_factory' - -module JavaBuildpack - module Container - - # Encapsulates the detect, compile, and release functionality for Tomcat gemfire support. - class TomcatGemfireStore < JavaBuildpack::Component::ModularComponent - include JavaBuildpack::Container - - # (see JavaBuildpack::Component::ModularComponent#command) - def compile - super - return unless supports? - mutate_context - mutate_server - create_client_cache_config - end - - protected - - # (see JavaBuildpack::Component::ModularComponent#sub_components) - def sub_components(context) - [ - GemFire.new(sub_configuration_context(context, 'gemfire')), - GemFireLog4jApi.new(sub_configuration_context(context, 'gemfire_log4j_api')), - GemFireLog4jCore.new(sub_configuration_context(context, 'gemfire_log4j_core')), - GemFireLog4jJcl.new(sub_configuration_context(context, 'gemfire_log4j_jcl')), - GemFireLog4jJul.new(sub_configuration_context(context, 'gemfire_log4j_jul')), - GemFireLog4jSlf4jImpl.new(sub_configuration_context(context, 'gemfire_log4j_slf4j_impl')), - GemFireLoggingApi.new(sub_configuration_context(context, 'gemfire_logging_api')), - GemFireLogging.new(sub_configuration_context(context, 'gemfire_logging')), - GemFireModules.new(sub_configuration_context(context, 'gemfire_modules')), - GemFireModulesTomcat7.new(sub_configuration_context(context, 'gemfire_modules_tomcat7')), - GemFireSecurity.new(sub_configuration_context(context, 'gemfire_security')) - ] - end - - # (see JavaBuildpack::Component::ModularComponent#command) - def command - return unless supports? - credentials = @application.services.find_service(FILTER)['credentials'] - @droplet.java_opts.add_system_property 'gemfire.security-username', credentials[KEY_USERNAME] - @droplet.java_opts.add_system_property 'gemfire.security-password', credentials[KEY_PASSWORD] - @droplet.java_opts.add_system_property 'gemfire.security-client-auth-init', - 'templates.security.UserPasswordAuthInit.create' - end - - # (see JavaBuildpack::Component::ModularComponent#supports?) - def supports? - @application.services.one_service? FILTER, KEY_LOCATORS, KEY_USERNAME, KEY_PASSWORD - end - - private - - FILTER = /session_replication/ - - FLUSH_VALVE_CLASS_NAME = 'com.gopivotal.manager.SessionFlushValve'.freeze - - GEMFIRE_LISTENER_CLASS = 'com.gemstone.gemfire.modules.session.catalina.ClientServerCacheLifecycleListener'.freeze - - KEY_LOCATORS = 'locators'.freeze - - KEY_PASSWORD = 'password'.freeze - - KEY_USERNAME = 'username'.freeze - - PERSISTENT_MANAGER_CLASS = 'com.gemstone.gemfire.modules.session.catalina.Tomcat7DeltaSessionManager'.freeze - - private_constant :FILTER, :FLUSH_VALVE_CLASS_NAME, :KEY_LOCATORS, :KEY_PASSWORD, :KEY_USERNAME, - :PERSISTENT_MANAGER_CLASS, :GEMFIRE_LISTENER_CLASS - - def mutate_context - document = read_xml context_xml - context = REXML::XPath.match(document, '/Context').first - add_manager context - write_xml context_xml, document - end - - def mutate_server - document = read_xml server_xml - server = REXML::XPath.match(document, '/Server').first - - add_listener server - write_xml server_xml, document - end - - def create_client_cache_config - document = REXML::Document.new - document << REXML::XMLDecl.new('1.0', 'UTF-8') - document << REXML::DocType.new('client-cache PUBLIC', - '"-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN" ' \ - '"http://www.gemstone.com/dtd/cache7_0.dtd"') - add_client_pool document - - write_xml client_cache_xml_path, document - end - - def add_manager(context) - context.add_element 'Manager', - 'className' => PERSISTENT_MANAGER_CLASS, - 'enableDebugListener' => 'false', - 'enableGatewayReplication' => 'false', - 'enableLocalCache' => 'true', - 'enableCommitValve' => 'true', - 'preferDeserializedForm' => 'true', - 'regionAttributesId' => 'PARTITION_REDUNDANT_PERSISTENT_OVERFLOW', - 'regionName' => 'sessions' - end - - def add_listener(server) - server.add_element 'Listener', - 'className' => GEMFIRE_LISTENER_CLASS, - 'cache-xml-file' => client_cache_xml_name, - 'criticalHeapPercentage' => '0.0', - 'evictionHeapPercentage' => '80.0', - 'log-file' => gemfire_log_file, - 'statistic-archive-file' => gemfire_statistics_file, - 'statistic-sampling-enabled' => 'false' - end - - def add_client_pool(document) - client = document.add_element 'client-cache' - - pool = client.add_element 'pool', - 'name' => 'sessions', - 'subscription-enabled' => 'true' - apply_locators_to_cache_client pool - end - - def apply_locators_to_cache_client(pool) - credentials = @application.services.find_service(FILTER)['credentials'] - - credentials[KEY_LOCATORS].each do |locator| - captures = locator.match(/([\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})\[([\d]{1,6})\]/) - pool.add_element 'locator', - 'host' => captures[1], - 'port' => captures[2] - end - end - - def client_cache_xml_path - @droplet.sandbox + 'conf' + client_cache_xml_name - end - - def client_cache_xml_name - 'cache-client.xml' - end - - def gemfire_log_file - 'gemfire_modules.log' - end - - def gemfire_statistics_file - 'gemfire_modules.gfs' - end - - end - - end -end diff --git a/spec/fixtures/container_tomcat_gemfire_store_cache_client_after.xml b/spec/fixtures/container_tomcat_gemfire_store_cache_client_after.xml deleted file mode 100644 index 729788cece..0000000000 --- a/spec/fixtures/container_tomcat_gemfire_store_cache_client_after.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/spec/fixtures/container_tomcat_gemfire_store_context_after.xml b/spec/fixtures/container_tomcat_gemfire_store_context_after.xml deleted file mode 100644 index b8146ba5a2..0000000000 --- a/spec/fixtures/container_tomcat_gemfire_store_context_after.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/spec/fixtures/container_tomcat_gemfire_store_server_after.xml b/spec/fixtures/container_tomcat_gemfire_store_server_after.xml deleted file mode 100644 index 36abd6188f..0000000000 --- a/spec/fixtures/container_tomcat_gemfire_store_server_after.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api_spec.rb deleted file mode 100644 index 76e028e2da..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_api_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_api' - -describe JavaBuildpack::Container::GemFireLog4jApi do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-log4j-api=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-log4j-api.jar' do - - component.compile - - expect(sandbox + "lib/log4j-api-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core_spec.rb deleted file mode 100644 index f013711cfa..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_core_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_core' - -describe JavaBuildpack::Container::GemFireLog4jCore do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-log4j-core=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-log4j-core.jar' do - - component.compile - - expect(sandbox + "lib/log4j-core-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl_spec.rb deleted file mode 100644 index 07351ed96e..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_jcl' - -describe JavaBuildpack::Container::GemFireLog4jJcl do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-log4j-jcl=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-log4j-jcl.jar' do - - component.compile - - expect(sandbox + "lib/log4j-jcl-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul_spec.rb deleted file mode 100644 index 05cc3f74fb..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_jul' - -describe JavaBuildpack::Container::GemFireLog4jJul do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-log4j-jul=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-log4j-jul.jar' do - - component.compile - - expect(sandbox + "lib/log4j-jul-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl_spec.rb deleted file mode 100644 index a59875a92f..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_log4j_slf4j_impl' - -describe JavaBuildpack::Container::GemFireLog4jSlf4jImpl do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-log4j-slf4j-impl=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-log4j-slf4j-impl.jar' do - - component.compile - - expect(sandbox + "lib/log4j-slf4j-impl-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_logging_api_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_logging_api_spec.rb deleted file mode 100644 index 6cb2849dd5..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_logging_api_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_logging_api' - -describe JavaBuildpack::Container::GemFireLoggingApi do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-logging-api=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-slf4j-api.jar' do - - component.compile - - expect(sandbox + "lib/slf4j-api-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_logging_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_logging_spec.rb deleted file mode 100644 index aabcb14d24..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_logging_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_logging' - -describe JavaBuildpack::Container::GemFireLogging do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-logging=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-slf4j-jdk14.jar' do - - component.compile - - expect(sandbox + "lib/slf4j-jdk14-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_modules_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_modules_spec.rb deleted file mode 100644 index 27aec7a107..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_modules_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_modules' - -describe JavaBuildpack::Container::GemFireModules do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-modules=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-modules.jar' do - - component.compile - - expect(sandbox + "lib/gemfire-modules-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7_spec.rb deleted file mode 100644 index 5c9a534edd..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7' - -describe JavaBuildpack::Container::GemFireModulesTomcat7 do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-modules-tomcat7=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-modules-tomcat7.jar' do - - component.compile - - expect(sandbox + "lib/gemfire-modules-tomcat7-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_security_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_security_spec.rb deleted file mode 100644 index e3bb674468..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_security_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire_security' - -describe JavaBuildpack::Container::GemFireSecurity do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire-security=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire-security.jar' do - - component.compile - - expect(sandbox + "lib/gemfire-security-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/gemfire/gemfire_spec.rb b/spec/java_buildpack/container/tomcat/gemfire/gemfire_spec.rb deleted file mode 100644 index f967d96295..0000000000 --- a/spec/java_buildpack/container/tomcat/gemfire/gemfire_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/gemfire/gemfire' - -describe JavaBuildpack::Container::GemFire do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - it 'always detects' do - expect(component.detect).to eq("gem-fire=#{version}") - end - - it 'copies resources', - cache_fixture: 'stub-gemfire.jar' do - - component.compile - - expect(sandbox + "lib/gemfire-#{version}.jar").to exist - end - - it 'does nothing during release' do - component.release - end - -end diff --git a/spec/java_buildpack/container/tomcat/tomcat_gemfire_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_gemfire_store_spec.rb deleted file mode 100644 index 4526d6a170..0000000000 --- a/spec/java_buildpack/container/tomcat/tomcat_gemfire_store_spec.rb +++ /dev/null @@ -1,138 +0,0 @@ -# Encoding: utf-8 -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/container/tomcat/tomcat_gemfire_store' -require 'java_buildpack/container/tomcat/gemfire/gemfire' -require 'java_buildpack/container/tomcat/gemfire/gemfire_logging' -require 'java_buildpack/container/tomcat/gemfire/gemfire_logging_api' -require 'java_buildpack/container/tomcat/gemfire/gemfire_modules' -require 'java_buildpack/container/tomcat/gemfire/gemfire_modules_tomcat7' -require 'java_buildpack/container/tomcat/gemfire/gemfire_security' - -describe JavaBuildpack::Container::TomcatGemfireStore do - include_context 'component_helper' - - let(:component_id) { 'tomcat' } - - let(:component) { StubGemfireStore.new context } - - let(:configuration) do - { 'gemfire' => gemfire_configuration, - 'gemfire_modules' => gemfire_modules_configuration, - 'gemfire_modules_tomcat7' => gemfire_modules_tomcat7_configuration, - 'gemfire_security' => gemfire_security_configuration, - 'gemfire_logging' => gemfire_logging_configuration, - 'gemfire_logging_api' => gemfire_logging_api_configuration } - end - - let(:gemfire_configuration) { instance_double('gemfire-configuration') } - - let(:gemfire_modules_configuration) { instance_double('gemfire-modules-configuration') } - - let(:gemfire_modules_tomcat7_configuration) { instance_double('gemfire-modules_tomcat7-configuration') } - - let(:gemfire_security_configuration) { instance_double('gemfire-security-configuration') } - - let(:gemfire_logging_configuration) { instance_double('gemfire-logging-configuration') } - - let(:gemfire_logging_api_configuration) { instance_double('gemfire-logging-api-configuration') } - - it 'does not detect without a session_replication service' do - expect(component.detect).to be_nil - end - - it 'does nothing without a session_replication service during release' do - expect(component.command).to be_nil - end - - it 'creates submodules' do - allow(JavaBuildpack::Container::GemFire) - .to receive(:new).with(sub_configuration_context(gemfire_configuration)) - allow(JavaBuildpack::Container::GemFireModules) - .to receive(:new).with(sub_configuration_context(gemfire_modules_configuration)) - allow(JavaBuildpack::Container::GemFireModulesTomcat7) - .to receive(:new).with(sub_configuration_context(gemfire_modules_tomcat7_configuration)) - allow(JavaBuildpack::Container::GemFireSecurity) - .to receive(:new).with(sub_configuration_context(gemfire_security_configuration)) - allow(JavaBuildpack::Container::GemFireLogging) - .to receive(:new).with(sub_configuration_context(gemfire_logging_configuration)) - allow(JavaBuildpack::Container::GemFireLoggingApi) - .to receive(:new).with(sub_configuration_context(gemfire_logging_api_configuration)) - - component.sub_components context - end - - context do - - before do - allow(services).to receive(:one_service?).with(/session_replication/, 'locators', 'username', 'password') - .and_return(true) - allow(services).to receive(:find_service).and_return('credentials' => { 'locators' => %w(1.0.0.2[45] 1.0.0.4[54]), - 'username' => 'test-username', - 'password' => 'test-password' }) - allow(application_cache).to receive(:get).with('test-uri').and_return('f') - end - - it 'detect with a session_replication service' do - expect(component.detect).to be - end - - # rubocop:disable Metrics/LineLength - it 'returns command' do - expect(component.command).to eq(%w(test-opt-2 - test-opt-1 - -Dgemfire.security-username=test-username - -Dgemfire.security-password=test-password - -Dgemfire.security-client-auth-init=templates.security.UserPasswordAuthInit.create)) - end - # rubocop:enable Metrics/LineLength - - it 'mutates context.xml', - app_fixture: 'container_tomcat_gemfire_store' do - component.compile - expect((sandbox + 'conf/context.xml').read) - .to eq(Pathname.new('spec/fixtures/container_tomcat_gemfire_store_context_after.xml').read) - end - - it 'mutates server.xml', - app_fixture: 'container_tomcat_gemfire_store' do - component.compile - expect((sandbox + 'conf/server.xml').read) - .to eq(Pathname.new('spec/fixtures/container_tomcat_gemfire_store_server_after.xml').read) - end - - it 'creates cache-client.xml', - app_fixture: 'container_tomcat_gemfire_store' do - component.compile - expect((sandbox + 'conf/cache-client.xml').read) - .to eq(Pathname.new('spec/fixtures/container_tomcat_gemfire_store_cache_client_after.xml').read) - end - - end - -end - -class StubGemfireStore < JavaBuildpack::Container::TomcatGemfireStore - public :command, :sub_components, :supports? -end - -def sub_configuration_context(configuration) - c = context.clone - c[:configuration] = configuration - c -end From 6ff8e9dd70ed3fe5162cbe04a9e2117cb932d883 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 9 Mar 2017 12:10:42 -0800 Subject: [PATCH 245/812] More Gemfire Removal --- .../.java-buildpack/tomcat/conf/context.xml | 19 ------------ .../.java-buildpack/tomcat/conf/server.xml | 29 ------------------ spec/fixtures/stub-gemfire-log4j-api.jar | Bin 2658 -> 0 bytes spec/fixtures/stub-gemfire-log4j-core.jar | Bin 2658 -> 0 bytes spec/fixtures/stub-gemfire-log4j-jcl.jar | Bin 2658 -> 0 bytes spec/fixtures/stub-gemfire-log4j-jul.jar | Bin 2658 -> 0 bytes .../stub-gemfire-log4j-slf4j-impl.jar | Bin 2658 -> 0 bytes .../fixtures/stub-gemfire-modules-tomcat7.jar | Bin 2658 -> 0 bytes spec/fixtures/stub-gemfire-modules.jar | Bin 2658 -> 0 bytes spec/fixtures/stub-gemfire-security.jar | Bin 2658 -> 0 bytes spec/fixtures/stub-gemfire-slf4j-api.jar | Bin 2658 -> 0 bytes spec/fixtures/stub-gemfire-slf4j-jdk14.jar | Bin 2658 -> 0 bytes spec/fixtures/stub-gemfire.jar | Bin 2658 -> 0 bytes 13 files changed, 48 deletions(-) delete mode 100644 spec/fixtures/container_tomcat_gemfire_store/.java-buildpack/tomcat/conf/context.xml delete mode 100644 spec/fixtures/container_tomcat_gemfire_store/.java-buildpack/tomcat/conf/server.xml delete mode 100644 spec/fixtures/stub-gemfire-log4j-api.jar delete mode 100644 spec/fixtures/stub-gemfire-log4j-core.jar delete mode 100644 spec/fixtures/stub-gemfire-log4j-jcl.jar delete mode 100644 spec/fixtures/stub-gemfire-log4j-jul.jar delete mode 100644 spec/fixtures/stub-gemfire-log4j-slf4j-impl.jar delete mode 100644 spec/fixtures/stub-gemfire-modules-tomcat7.jar delete mode 100644 spec/fixtures/stub-gemfire-modules.jar delete mode 100644 spec/fixtures/stub-gemfire-security.jar delete mode 100644 spec/fixtures/stub-gemfire-slf4j-api.jar delete mode 100644 spec/fixtures/stub-gemfire-slf4j-jdk14.jar delete mode 100644 spec/fixtures/stub-gemfire.jar diff --git a/spec/fixtures/container_tomcat_gemfire_store/.java-buildpack/tomcat/conf/context.xml b/spec/fixtures/container_tomcat_gemfire_store/.java-buildpack/tomcat/conf/context.xml deleted file mode 100644 index 7f96549265..0000000000 --- a/spec/fixtures/container_tomcat_gemfire_store/.java-buildpack/tomcat/conf/context.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/spec/fixtures/container_tomcat_gemfire_store/.java-buildpack/tomcat/conf/server.xml b/spec/fixtures/container_tomcat_gemfire_store/.java-buildpack/tomcat/conf/server.xml deleted file mode 100644 index 61f11bcaa1..0000000000 --- a/spec/fixtures/container_tomcat_gemfire_store/.java-buildpack/tomcat/conf/server.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/spec/fixtures/stub-gemfire-log4j-api.jar b/spec/fixtures/stub-gemfire-log4j-api.jar deleted file mode 100644 index 55f9148b703689892d3495fe53bc64bc8d4e2520..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2658 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 Date: Thu, 9 Mar 2017 14:27:21 -0800 Subject: [PATCH 246/812] Example Documentation Improvements Previously, the examples for configuring the JRE referenced the Memory Calculator v2 configuration. This change updates the example to use Memory Calculator v3 configuration. [resolves #393] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf55ec8195..703cb7d7bf 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ The buildpack supports extension through the use of Git repository forking. The Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec ([Wikipedia] has a good description of this yaml syntax). For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. ```bash -$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ jre: { version: 1.7.0_+ }, memory_calculator: { memory_heuristics: { heap: 85, stack: 10 } } }' +$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ jre: { version: 1.8.0_+ }, memory_calculator: { stack_threads: 200 } }' ``` If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. From 9de12219f4fb332f3652bbabbc18d17a4eb9068a Mon Sep 17 00:00:00 2001 From: Victor Maevskiy Date: Fri, 10 Mar 2017 17:07:25 -0500 Subject: [PATCH 247/812] Prioritize Leading Digits in Qualifier Previously, when wildcarded qualifiers were compared, they were compared purely lexically. This disadvantaged versions that exclusively used numbers in the qualifier (e.g. Java versions). The result of this was that no matter what _121 would always fall before _91 which in turn led to some poor work arounds using the wildcards. This change now handles leading digits numerically rather than lexically, after which the rest of the qualifier is compared lexically. [#397][#402] --- lib/java_buildpack/util/tokenized_version.rb | 2 +- spec/java_buildpack/repository/version_resolver_spec.rb | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index c18b3674a8..109c9f158b 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -121,7 +121,7 @@ def minimum_qualifier_length(a, b) end def qualifier_compare(a, b) - comparison = 0 + comparison = a[/^\d+/].to_i <=> b[/^\d+/].to_i i = 0 until comparison.nonzero? || i == minimum_qualifier_length(a, b) diff --git a/spec/java_buildpack/repository/version_resolver_spec.rb b/spec/java_buildpack/repository/version_resolver_spec.rb index 0d704c584b..fc331f8ca7 100644 --- a/spec/java_buildpack/repository/version_resolver_spec.rb +++ b/spec/java_buildpack/repository/version_resolver_spec.rb @@ -22,7 +22,9 @@ describe JavaBuildpack::Repository::VersionResolver do include_context 'logging_helper' - let(:versions) { %w(1.6.0_26 1.6.0_27 1.6.1_14 1.7.0_19 1.7.0_21 1.8.0_M-7 1.8.0_05 2.0.0 2.0.0a) } + let(:versions) do + %w(1.6.0_26 1.6.0_27 1.6.0_112 1.6.0_102 1.6.0_45RELEASE 1.6.1_14 1.7.0_19 1.7.0_21 1.8.0_M-7 1.8.0_05 2.0.0 2.0.0a) + end it 'resolves the default version if no candidate is supplied' do expect(described_class.resolve(nil, versions)).to eq(tokenized_version('2.0.0')) @@ -41,7 +43,7 @@ end it 'resolves a wildcard qualifier' do - expect(described_class.resolve(tokenized_version('1.6.0_+'), versions)).to eq(tokenized_version('1.6.0_27')) + expect(described_class.resolve(tokenized_version('1.6.0_+'), versions)).to eq(tokenized_version('1.6.0_112')) expect(described_class.resolve(tokenized_version('1.8.0_+'), versions)).to eq(tokenized_version('1.8.0_05')) end From 814307a96f4c4dde865ad2f38e69350a7f9551d9 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 17 Mar 2017 10:50:11 -0700 Subject: [PATCH 248/812] Relax JRE Wildcards Thanks to the previous contribution we can now relax the JRE wildcards and still get the latest version. [#397][#402] --- config/open_jdk_jre.yml | 2 +- config/oracle_jre.yml | 2 +- config/zulu_jre.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index cc0c19deca..3bcf667af2 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -17,7 +17,7 @@ # If Java 7 is required, permgen will be used instead of metaspace. Please see the documentation for more detail. --- jre: - version: 1.8.0_12+ + version: 1.8.0_+ repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" memory_calculator: version: 2.+ diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index 8d9cff7765..e8951ebeb5 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -20,7 +20,7 @@ # e.g. repository_root: "http://example.com/oracle-jre/{platform}/{architecture}" --- jre: - version: 1.8.0_12+ + version: 1.8.0_+ repository_root: "" memory_calculator: version: 2.+ diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 47e4b955f3..e8eeff00ed 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -20,7 +20,7 @@ # e.g. repository_root: "http://example.com/zulu-jre/{platform}/{architecture}" --- jre: - version: 1.8.0_12+ + version: 1.8.0_+ repository_root: "https://cdn.azul.com/zulu/bin" memory_calculator: version: 2.+ From e81b76f45febae379aa42f21e9369e6c2ada385a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 21 Mar 2017 08:49:44 -0700 Subject: [PATCH 249/812] Reinstate JRebel This change reinstates the JRebel framework now that there is more clarity in licensing and distribution. --- config/components.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/components.yml b/config/components.yml index f4b92ce5b1..88024998f9 100644 --- a/config/components.yml +++ b/config/components.yml @@ -45,7 +45,7 @@ frameworks: - "JavaBuildpack::Framework::DynatraceOneAgent" # - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::Jmx" -# - "JavaBuildpack::Framework::JrebelAgent" + - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::LunaSecurityProvider" - "JavaBuildpack::Framework::DyadicEkmSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" From cdf7459c6cbf72f50d5b7bf896317b5bb62a4e47 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 22 Mar 2017 10:26:24 -0700 Subject: [PATCH 250/812] killjava.sh Is Executable Previously, changes to the packaging script to ensure that executable permissions were propagated in all packaging circumstances missed that the killjava.sh script needed to be executable as well. This change updates the packaging script to broaden the collection of files that get executable permissions during packaging. [resolves #408] --- rakelib/stage_buildpack_task.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/stage_buildpack_task.rb b/rakelib/stage_buildpack_task.rb index 097f3d4851..ed130572e0 100644 --- a/rakelib/stage_buildpack_task.rb +++ b/rakelib/stage_buildpack_task.rb @@ -38,7 +38,7 @@ def copy_task(source, target) file(target => [source, parent]) do |t| cp t.source, t.name - if t.source.start_with? 'bin' + if t.source.include? 'bin' chmod 0o755, t.name else chmod 0o644, t.name From 737093b6abfbd18e055a3b37349e5352ab572b1a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 24 Mar 2017 14:09:14 -0700 Subject: [PATCH 251/812] Print JVM Memory Configuration on Startup Previously, the JVM memory configuration was printed on startup by the memory calculator itself. Because the memory calculator stdout is captured, this printing had to be done to stderr. This caused some alarm (mostly by Sabby), so this alternative was created. This change prints the captured output (plus some other verbage), removing the need for the memory calculator to do it. --- lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb | 3 ++- .../jre/open_jdk_like_memory_calculator_spec.rb | 6 ++++-- spec/java_buildpack/jre/open_jdk_like_spec.rb | 6 ++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 557d0b5b8b..c4b3ba6a53 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -53,7 +53,8 @@ def compile # # @return [String] the memory calculation command def memory_calculation_command - "CALCULATED_MEMORY=$(#{memory_calculation_string(@droplet.root)})" + "CALCULATED_MEMORY=$(#{memory_calculation_string(@droplet.root)}) && " \ + 'echo JVM Memory Configuration: $CALCULATED_MEMORY' end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 832933e634..414fd35c94 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -91,7 +91,8 @@ expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ - '-loadedClasses=2 -poolType=metaspace)') + '-loadedClasses=2 -poolType=metaspace) && echo JVM Memory Configuration: ' \ + '$CALCULATED_MEMORY') end context do @@ -107,7 +108,8 @@ expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ - '-loadedClasses=2 -poolType=metaspace -vmOptions=\'-Dalpha=bravo\')') + '-loadedClasses=2 -poolType=metaspace -vmOptions=\'-Dalpha=bravo\') && echo JVM Memory ' \ + 'Configuration: $CALCULATED_MEMORY') end end diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index 702b1cd0c3..c34493b583 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -66,7 +66,8 @@ java_home.version = version_7 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ - ' -stackThreads=200 -loadedClasses=0 -poolType=permgen)') + ' -stackThreads=200 -loadedClasses=0 -poolType=permgen) && echo JVM Memory ' \ + 'Configuration: $CALCULATED_MEMORY') end @@ -74,7 +75,8 @@ java_home.version = version_8 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ - ' -stackThreads=200 -loadedClasses=0 -poolType=metaspace)') + ' -stackThreads=200 -loadedClasses=0 -poolType=metaspace) && echo JVM Memory ' \ + 'Configuration: $CALCULATED_MEMORY') end From 566cf19f564f9024370a615b3c70e1bf32661155 Mon Sep 17 00:00:00 2001 From: Mike Jacobi Date: Fri, 24 Mar 2017 10:19:26 -0700 Subject: [PATCH 252/812] Clarify package documentation This change adds the `clean` argument to the packaging documentation to ensure that builds come from fresh systems. [#410] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a2e76763e..81808813d0 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ To pin the version of dependencies used by the buildpack to the ones currently r ```bash $ bundle install -$ bundle exec rake package OFFLINE=true PINNED=true +$ bundle exec rake clean package OFFLINE=true PINNED=true ... Creating build/java-buildpack-offline-cfd6b17.zip ``` From 180eb69fc405fb27d19365cca0e21a762c3ecf54 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 27 Mar 2017 11:26:59 -0700 Subject: [PATCH 253/812] Additional documentation This change adds some addition clarifying documentation about cleaning before package builds. [resolves #410] --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 81808813d0..b7822e6866 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ The online package is a version of the buildpack that is as minimal as possible ```bash $ bundle install -$ bundle exec rake package +$ bundle exec rake clean package ... Creating build/java-buildpack-cfd6b17.zip ``` @@ -144,7 +144,7 @@ Keeping track of different versions of the buildpack can be difficult. To help ```bash $ bundle install -$ bundle exec rake package VERSION=2.1 +$ bundle exec rake clean package VERSION=2.1 ... Creating build/java-buildpack-2.1.zip ``` From fd973b2f6f31637b956766cde3f586f306b44179 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 27 Mar 2017 14:28:54 -0700 Subject: [PATCH 254/812] Upgrade Docker Image to include 2.4.1 --- ci/docker-image/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 27b2902a2c..8f5ebd9d0f 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -36,4 +36,4 @@ RUN eval "$(rbenv init -)" \ && rbenv install 2.3.3 RUN eval "$(rbenv init -)" \ - && rbenv install 2.4.0 + && rbenv install 2.4.1 From 6b4df41ef3c48bc9560894cfbcb1b78fbf48efd2 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 27 Mar 2017 14:28:54 -0700 Subject: [PATCH 255/812] Upgrade Docker Image to include 2.4.1 --- ci/docker-image/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 27b2902a2c..8f5ebd9d0f 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -36,4 +36,4 @@ RUN eval "$(rbenv init -)" \ && rbenv install 2.3.3 RUN eval "$(rbenv init -)" \ - && rbenv install 2.4.0 + && rbenv install 2.4.1 From 751075c3726fcf17d137fd5b78034c6f7bca04fc Mon Sep 17 00:00:00 2001 From: Ben Dalby Date: Wed, 29 Mar 2017 10:58:31 +0100 Subject: [PATCH 256/812] Update README.md Added note to clarify Windows is not supported for developing this buildpack. See GSS issue #50856 for further context. [resolves #411] --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b7822e6866..04fdcf31f8 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,9 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Java Buildpack System Tests](https://github.com/cloudfoundry/java-buildpack-system-test) ## Building Packages -The buildpack can be packaged up so that it can be uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used. +The buildpack can be packaged up so that it can be uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used. + +Note that this process is not currently supported on Windows. It is possible it will work, but it is not tested, and no additional functionality has been added to make it work. ### Online Package The online package is a version of the buildpack that is as minimal as possible and is configured to connect to the network for all dependencies. This package is about 50K in size. To create the online package, run: From f7a1b85d5ac40bb20b30cd945959649d167772fe Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 5 Apr 2017 08:15:35 -0700 Subject: [PATCH 257/812] Add Google Stackdriver Debugger Framework This change adds support for the Google Stackdriver Debugger (https://cloud.google.com/debugger/) to the buildpack. It expects a bound service (google-stackdriver-debugger) with module and version credentials. [resolves #405] --- README.md | 3 +- config/components.yml | 1 + config/google_stackdriver_debugger.yml | 19 +++++ docs/framework-google_stackdriver_debugger.md | 43 ++++++++++ java-buildpack.iml | 4 +- .../component/base_component.rb | 9 +- .../versioned_dependency_component.rb | 5 +- .../framework/google_stackdriver_debugger.rb | 78 ++++++++++++++++++ spec/application_helper.rb | 5 +- .../stub-google-stackdriver-debugger.tar.gz | Bin 0 -> 163 bytes .../google_stackdriver_debugger_spec.rb | 75 +++++++++++++++++ 11 files changed, 234 insertions(+), 8 deletions(-) create mode 100644 config/google_stackdriver_debugger.yml create mode 100644 docs/framework-google_stackdriver_debugger.md create mode 100644 lib/java_buildpack/framework/google_stackdriver_debugger.rb create mode 100644 spec/fixtures/stub-google-stackdriver-debugger.tar.gz create mode 100644 spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb diff --git a/README.md b/README.md index 04fdcf31f8..9f1b692bfd 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Dyadic EKM Security Provider](docs/framework-dyadic_ekm_security_provider.md) ([Configuration](docs/framework-dyadic_ekm_security_provider.md#configuration)) * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) + * [Google Stackdriver Debugger](docs/framework-google_stackdriver_debugger.md) ([Configuration](docs/framework-google_stackdriver_debugger.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) @@ -115,7 +116,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Java Buildpack System Tests](https://github.com/cloudfoundry/java-buildpack-system-test) ## Building Packages -The buildpack can be packaged up so that it can be uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used. +The buildpack can be packaged up so that it can be uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used. Note that this process is not currently supported on Windows. It is possible it will work, but it is not tested, and no additional functionality has been added to make it work. diff --git a/config/components.yml b/config/components.yml index 88024998f9..747009c72e 100644 --- a/config/components.yml +++ b/config/components.yml @@ -43,6 +43,7 @@ frameworks: - "JavaBuildpack::Framework::Debug" - "JavaBuildpack::Framework::DynatraceAppmonAgent" - "JavaBuildpack::Framework::DynatraceOneAgent" + - "JavaBuildpack::Framework::GoogleStackdriverDebugger" # - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::Jmx" - "JavaBuildpack::Framework::JrebelAgent" diff --git a/config/google_stackdriver_debugger.yml b/config/google_stackdriver_debugger.yml new file mode 100644 index 0000000000..d79b3a1238 --- /dev/null +++ b/config/google_stackdriver_debugger.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Groovy container +--- +version: 2.+ +repository_root: "{default.repository.root}/google-stackdriver-debugger/{platform}/{architecture}" diff --git a/docs/framework-google_stackdriver_debugger.md b/docs/framework-google_stackdriver_debugger.md new file mode 100644 index 0000000000..63f911614c --- /dev/null +++ b/docs/framework-google_stackdriver_debugger.md @@ -0,0 +1,43 @@ +# Google Stackdriver Debugger Framework +The Google Stackdriver Debugger Framework causes an application to be automatically configured to work with a bound [Google Stackdriver Debugger Service][]. + +
+ + + + + + + +
Detection CriterionExistence of a single bound Google Stackdriver Debugger service. +
    +
  • Existence of a Google Stackdriver Debugger service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has google-stackdriver-debugger as a substring.
  • +
+
Tagsgoogle-stackdriver-debugger=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service (Optional) +Users may optionally provide their own Google Stackdriver Debugger service. A user-provided Google Stackdriver Debugger service must have a name or tag with `google-stackdriver-debugger` in it so that the Google Stackdriver Debugger Agent Framework will automatically configure the application to work with the service. + +The credential payload of the service must contain the following entry: + +| Name | Description +| ---- | ----------- +| `PrivateKeyData` | A Base64 encoded Service Account JSON payload + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/google_stackdriver_debugger.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Google Stackdriver Debugger repository index ([details][repositories]). +| `version` | The version of Google Stackdriver Debugger to use. Candidate versions can be found in [this listing][]. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[`config/google_stackdriver_debugger.yml`]: ../config/google_stackdriver_debugger.yml +[Google Stackdriver Debugger Service]: https://cloud.google.com/debugger/ +[repositories]: extending-repositories.md +[this listing]: http://download.pivotal.io.s3.amazonaws.com/google-stackdriver-debugger/trusty/x86_64/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/java-buildpack.iml b/java-buildpack.iml index 913886a745..a67d4ab86d 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -255,7 +255,7 @@
- + @@ -269,7 +269,7 @@ - + diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index fd2be446da..1d8e5ebb23 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -114,21 +114,26 @@ def download_jar(version, uri, jar_name, target_directory = @droplet.sandbox, na # # @param [String] version the version of the download # @param [String] uri the uri of the download + # @param [Boolean] strip_top_level whether to strip the top-level directory when expanding. Defaults to +true+. # @param [Pathname] target_directory the directory to expand the TAR file to. Defaults to the component's # sandbox. # @param [String] name an optional name for the download and expansion. Defaults to +@component_name+. # @return [Void] - def download_tar(version, uri, target_directory = @droplet.sandbox, name = @component_name) + def download_tar(version, uri, strip_top_level = true, target_directory = @droplet.sandbox, + name = @component_name) download(version, uri, name) do |file| with_timing "Expanding #{name} to #{target_directory.relative_path_from(@droplet.root)}" do FileUtils.mkdir_p target_directory - shell "tar x#{compression_flag(file)}f #{file.path} -C #{target_directory} --strip 1 2>&1" + shell "tar x#{compression_flag(file)}f #{file.path} -C #{target_directory} " \ + "#{'--strip 1' if strip_top_level} 2>&1" end end end # Downloads a given ZIP file and expands it. # + # @param [String] version the version of the download + # @param [String] uri the uri of the download # @param [Boolean] strip_top_level whether to strip the top-level directory when expanding. Defaults to +true+. # @param [Pathname] target_directory the directory to expand the ZIP file to. Defaults to the component's # sandbox. diff --git a/lib/java_buildpack/component/versioned_dependency_component.rb b/lib/java_buildpack/component/versioned_dependency_component.rb index b3c84f2197..935cd183b5 100644 --- a/lib/java_buildpack/component/versioned_dependency_component.rb +++ b/lib/java_buildpack/component/versioned_dependency_component.rb @@ -71,12 +71,13 @@ def download_jar(jar_name = self.jar_name, target_directory = @droplet.sandbox, # Downloads a given TAR file and expands it. # + # @param [Boolean] strip_top_level whether to strip the top-level directory when expanding. Defaults to +true+. # @param [Pathname] target_directory the directory to expand the TAR file to. Defaults to the component's # sandbox. # @param [String] name an optional name for the download and expansion. Defaults to +@component_name+. # @return [Void] - def download_tar(target_directory = @droplet.sandbox, name = @component_name) - super(@version, @uri, target_directory, name) + def download_tar(strip_top_level = true, target_directory = @droplet.sandbox, name = @component_name) + super(@version, @uri, strip_top_level, target_directory, name) end # Downloads a given ZIP file and expands it. diff --git a/lib/java_buildpack/framework/google_stackdriver_debugger.rb b/lib/java_buildpack/framework/google_stackdriver_debugger.rb new file mode 100644 index 0000000000..7a0fc1252f --- /dev/null +++ b/lib/java_buildpack/framework/google_stackdriver_debugger.rb @@ -0,0 +1,78 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'base64' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Google Cloud Debugger support. + class GoogleStackdriverDebugger < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_tar false + + credentials = @application.services.find_service(FILTER)['credentials'] + write_json_file credentials[PRIVATE_KEY_DATA] + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + java_opts = @droplet.java_opts + + java_opts + .add_agentpath_with_props(@droplet.sandbox + 'cdbg_java_agent.so', '--logtostderr' => 1) + .add_system_property('com.google.cdbg.auth.serviceaccount.enable', true) + .add_system_property('com.google.cdbg.auth.serviceaccount.jsonfile', json_file) + .add_system_property('com.google.cdbg.module', @application.details['application_name']) + .add_system_property('com.google.cdbg.version', @application.details['application_version']) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, PRIVATE_KEY_DATA + end + + FILTER = /google-stackdriver-debugger/ + + PRIVATE_KEY_DATA = 'PrivateKeyData'.freeze + + private_constant :FILTER, :PRIVATE_KEY_DATA + + private + + def json_file + @droplet.sandbox + 'svc.json' + end + + def write_json_file(json_file_data) + FileUtils.mkdir_p json_file.parent + json_file.open(File::CREAT | File::WRONLY) do |f| + f.write "#{Base64.decode64 json_file_data}\n" + f.sync + f + end + end + + end + + end +end diff --git a/spec/application_helper.rb b/spec/application_helper.rb index bb01d0fa41..44c53c3b2a 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -46,7 +46,10 @@ let(:services) { application.services } - let(:vcap_application) { { 'application_name' => 'test-application-name' } } + let(:vcap_application) do + { 'application_name' => 'test-application-name', + 'application_version' => 'test-application-version' } + end let(:vcap_services) do { 'test-service-n/a' => [{ 'name' => 'test-service-name', 'label' => 'test-service-n/a', diff --git a/spec/fixtures/stub-google-stackdriver-debugger.tar.gz b/spec/fixtures/stub-google-stackdriver-debugger.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8fb7fc3e92bc20ada8561f78f9e7341485e8e0c7 GIT binary patch literal 163 zcmb2|=3ub%JQKmd{PtorSF?dYYvS}tq9>Njob}XWOO|%h!6mWvTg^3C7e4TQ_&<(M z@w36nmHeUM-yTYxx?q}o>apeRIUORa(mdneyw}`){O8dK^;Y3fQPZTW-Di7p_Mh7B z?UOhwd}Uu^M%c4w8@I*otl#%|ZvCQvZ}!{tuAF(y;K-i&`%|U&e}BKW^b0=&GRV%e MlQPX=&|qKy0ONE@i~s-t literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb b/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb new file mode 100644 index 0000000000..94c4810824 --- /dev/null +++ b/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb @@ -0,0 +1,75 @@ +# Encoding: utf-8 +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/google_stackdriver_debugger' + +describe JavaBuildpack::Framework::GoogleStackdriverDebugger do + include_context 'component_helper' + + it 'does not detect without google-stackdriver-debugger-n/a service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?) + .with(/google-stackdriver-debugger/, 'PrivateKeyData').and_return(true) + + allow(services).to receive(:find_service).and_return( + 'credentials' => { + 'PrivateKeyData' => 'dGVzdC1wcml2YXRlLWtleS1kYXRh' + } + ) + end + + it 'detects with google-stackdriver-debugger-c-n/a service' do + expect(component.detect).to eq("google-stackdriver-debugger=#{version}") + end + + it 'unpacks the google stackdriver debugger tar', + cache_fixture: 'stub-google-stackdriver-debugger.tar.gz' do + + component.compile + + expect(sandbox + 'cdbg_java_agent.so').to exist + end + + it 'writes JSOn file', + cache_fixture: 'stub-google-stackdriver-debugger.tar.gz' do + + component.compile + + expect(sandbox + 'svc.json').to exist + expect(File.read(sandbox + 'svc.json')).to eq("test-private-key-data\n") + end + + it 'updates JAVA_OPTS' do + component.release + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/google_stackdriver_debugger/cdbg_java_agent.so=' \ + '--logtostderr=1') + expect(java_opts).to include('-Dcom.google.cdbg.auth.serviceaccount.enable=true') + expect(java_opts).to include('-Dcom.google.cdbg.auth.serviceaccount.jsonfile=' \ + '$PWD/.java-buildpack/google_stackdriver_debugger/svc.json') + expect(java_opts).to include('-Dcom.google.cdbg.module=test-application-name') + expect(java_opts).to include('-Dcom.google.cdbg.version=test-application-version') + end + + end + +end From fe53fe089a603fa72d589203fb3a9348efa665b8 Mon Sep 17 00:00:00 2001 From: Nikhil Katre Date: Thu, 16 Mar 2017 14:30:33 -0700 Subject: [PATCH 258/812] Re-enable AppDynamics Framework This change re-enables the previously disabled AppDynamics framework. This change also updates the repository configuration to point at a repository hosted by AppDynamics, adjusts the application naming convention. [#404] --- config/app_dynamics_agent.yml | 5 +++-- config/components.yml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 89914eb65f..e2374bfd96 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -16,8 +16,9 @@ # Configuration for the AppDynamics framework --- version: 4.+ -repository_root: "" -default_application_name: +repository_root: "https://packages.appdynamics.com/java" +default_application_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); + puts \"#{a['space_name']}:#{a['application_name']}\"") default_node_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); puts \"#{a['application_name']}:#{a['instance_index']}\"") default_tier_name: diff --git a/config/components.yml b/config/components.yml index 747009c72e..24aa53968c 100644 --- a/config/components.yml +++ b/config/components.yml @@ -37,7 +37,7 @@ jres: # command after any Java Opts added by previous frameworks. frameworks: -# - "JavaBuildpack::Framework::AppDynamicsAgent" + - "JavaBuildpack::Framework::AppDynamicsAgent" - "JavaBuildpack::Framework::ContainerCertificateTrustStore" - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::Debug" From 2dd71800f6d2a214e4543636f64ba677d21578a7 Mon Sep 17 00:00:00 2001 From: Glyn Normington Date: Mon, 10 Apr 2017 14:07:17 +0100 Subject: [PATCH 259/812] Update memory calculation docs --- docs/jre-open_jdk_jre.md | 99 ++++++++++++++++++-------------------- docs/jre-oracle_jre.md | 100 +++++++++++++++++++------------------- docs/jre-zulu_jre.md | 101 +++++++++++++++++++-------------------- 3 files changed, 143 insertions(+), 157 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 13d8157bd4..6a25e34bcb 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -20,9 +20,7 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | Name | Description | ---- | ----------- -| `memory_sizes` | Optional memory sizes, described below under "Memory Sizes". -| `memory_heuristics` | Default memory size weightings, described below under "Memory Weightings". -| `memory_initials` | Initial memory sizes, described below under "Memory Initials". +| `memory_calculator` | Memory calculator defaults, described below under "Memory". | `repository_root` | The URL of the OpenJDK repository index ([details][repositories]). | `version` | The version of Java runtime to use. Candidate versions can be found in the listings for [mountainlion][], [precise][], and [trusty][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. @@ -36,81 +34,78 @@ To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resource To add custom SSL certificates, add your `cacerts` file to `resources/open_jdk_jre/lib/security/cacerts`. This file will be overlayed onto the OpenJDK distribution. ### Memory -The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials` and/or `stack_threads` mappings. +The total available memory for the application's container is specified when an application is pushed. +The Java buildpack uses this value to control the JRE's use of various +regions of memory and logs the JRE memory settings when the application starts or restarts. +These settings can be influenced by configuring +the `stack_threads` and/or `class_count` mappings (both part of the `memory_calculator` mapping), +and/or Java options relating to memory. Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. -Note: If setting an initial Stack size, depending on the version of Java and the operating system used by Cloud Foundry the JRE will require a minimum `-Xss` value. This tends to be between `100k` and `250k`. +#### Total Memory -#### Memory Sizes -The following optional properties may be specified in the `memory_sizes` mapping. +The user can change the container's total memory available to influence the JRE memory settings. +Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory +available results in the heap size setting increasing or decreasing by a corresponding amount. -| Name | Description -| ---- | ----------- -| `heap` | The maximum heap size to use. It may be a single value such as `64m` or a range of acceptable values such as `128m..256m`. It is used to calculate the value of the Java command line options `-Xmx` and `-Xms`. -| `metaspace` | The maximum Metaspace size to use. It is applicable to versions of OpenJDK from 1.8 onwards. It may be a single value such as `64m` or a range of acceptable values such as `128m..256m`. It is used to calculate the value of the Java command line options `-XX:MaxMetaspaceSize=` and `-XX:MetaspaceSize=`. -| `native` | The amount of memory to reserve for native memory allocation. It should normally be omitted or specified as a range with no upper bound such as `100m..`. It does not correspond to a switch on the Java command line. -| `permgen` | The maximum PermGen size to use. It is applicable to versions of OpenJDK earlier than 1.8. It may be a single value such as `64m` or a range of acceptable values such as `128m..256m`. It is used to calculate the value of the Java command line options `-XX:MaxPermSize=` and `-XX:PermSize=`. -| `stack` | The stack size to use. It may be a single value such as `2m` or a range of acceptable values such as `2m..4m`. It is used to calculate the value of the Java command line option `-Xss`. - -Memory sizes together with _memory weightings_ (described in the next section) are used to calculate the amount of memory for each memory type. The calculation is described later. - -Memory sizes consist of a non-negative integer followed by a unit (`k` for kilobytes, `m` for megabytes, `g` for gigabytes; the case is not significant). Only the memory size `0` may be specified without a unit. - -The above memory size properties may be omitted with an empty value, specified as a single value, or specified as a range. Ranges use the syntax `..`, although either bound may be omitted in which case the defaults of zero and the total available memory are used for the lower bound and upper bound, respectively. Examples of ranges are `100m..200m` (any value between 100 and 200 megabytes, inclusive) and `100m..` (any value greater than or equal to 100 megabytes). - -Each form of memory size is equivalent to a range. Omitting a memory size is equivalent to specifying the range `0..`. Specifying a single value is equivalent to specifying the range with that value as both the lower and upper bound, for example `128m` is equivalent to the range `128m..128m`. +#### Stack Threads -#### Memory Weightings -Memory weightings are configured in the `memory_heuristics` mapping of [`config/open_jdk_jre.yml`][]. Each weighting is a non-negative number and represents a proportion of the total available memory (represented by the sum of all the weightings). For example, the following weightings: +The amount of memory that should be allocated to stacks is given as an amount of memory per +thread with the Java option `-Xss`. If an explicit number of +threads should be used for the calculation of stack memory, then it should be specified as in +the following example: ```yaml -memory_heuristics: - heap: 15 - native: 2 - permgen: 5 - stack: 1 +stack_threads: 500 ``` -represent a maximum heap size three times as large as the maximum PermGen size, and so on. - -Memory weightings are used together with memory ranges to calculate the amount of memory for each memory type, as follows. +#### Loaded Classes -#### Memory Initials -Memory initials are configured in the `memory_initials` mapping of [`config/open_jdk_jre.yml`][]. Each initial is a percentage of the given type of memory. Valid memory types are `heap`, `permgen`, and `metaspace`. For example, the following initials: +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: ```yaml -memory_initials: - heap: 50% - permgen: 25% +class_count: 500 ``` -Given a maximum heap (Xmx) of 1G and a maximum permgen (-XX:MaxPermsize) of 256M an initial heap (Xms) of 512M and an initial permgen (-XX:Permsize) of 64M would be used. - -If no initial value is specified for a memory type the JVM default will be used. - -A value of 100% for each memory types is generally recommended for best performance. Smaller values will potentially preserve unused system memory for other tenants on the same host. Using the G1 garbage collector along with aggressive `MinHeapFreeRatio` and `MaxHeapFreeRatio` values the JVM will actually release unused heap back to the system up to the initial value. - -#### Stack Threads - -The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory then it should be specified like the following example: +#### Java Options -```yaml -stack_threads: 500 -``` +If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to +specific values. The heap size can be set explicitly, but changing the value of options other +than the heap size can also affect the heap size. For example, if the user increases +the maximum direct memory size from its default value of 10 Mb to 20 Mb, then this will +reduce the calculated heap size by 10 Mb. #### Memory Calculation Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. -The total available memory is allocated into heap, Metaspace or PermGen (depending on the version of Oracle), stack, and native memory types. +The container's total available memory is allocated into heap, metaspace and compressed class space (or permanent generation for Java 7), +direct memory, and stack memory settings. + +The memory calculation is described in more detail in the [Memory Calculator's README]. + +The inputs to the memory calculation, except the container's total memory (which is unknown at staging time), are logged during staging, for example: +``` +Loaded Classes: 13974, Threads: 300, JAVA_OPTS: '' +``` -The total available memory is first allocated to each memory type in proportion to its weighting (this is called ‘balancing'). If the resultant size of any memory type lies outside its range, the size is constrained to the range, the constrained size is excluded from the remaining memory, and no further calculation is required for that memory type. The remaining memory is then balanced against the memory types that are left, and the check is repeated until no calculated memory sizes lie outside their ranges. The remaining memory is then allocated to the remaining memory types according to the last balance step. This iteration terminates when none of the sizes of the remaining memory types is constrained by their corresponding ranges. +The container's total memory is logged during `cf push` and `cf scale`, for example: +``` + state since cpu memory disk details +#0 running 2017-04-10 02:20:03 PM 0.0% 896K of 1G 1.3M of 1G +``` -Termination is guaranteed since there is a finite number of memory types and in each iteration either none of the remaining memory sizes is constrained by the corresponding range and allocation terminates or at least one memory size is constrained by the corresponding range and is omitted from the next iteration. +The JRE memory settings are logged when the application is started or re-started, for example: +``` +JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199K \ + -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=18134K -Xss1M -Xmx368042K +``` [`config/open_jdk_jre.yml`]: ../config/open_jdk_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [mountainlion]: http://download.pivotal.io.s3.amazonaws.com/openjdk/mountainlion/x86_64/index.yml [OpenJDK]: http://openjdk.java.net [precise]: http://download.pivotal.io.s3.amazonaws.com/openjdk/precise/x86_64/index.yml diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 14bb171c06..19ba348fe8 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -36,9 +36,7 @@ To use Oracle JRE instead of OpenJDK without forking java-buildpack, set environ | Name | Description | ---- | ----------- -| `memory_sizes` | Optional memory sizes, described below under "Memory Sizes". -| `memory_heuristics` | Default memory size weightings, described below under "Memory Weightings". -| `memory_initials` | Initial memory sizes, described below under "Memory Initials". +| `memory_calculator` | Memory calculator defaults, described below under "Memory". | `repository_root` | The URL of the Oracle repository index ([details][repositories]). | `version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. @@ -50,83 +48,81 @@ To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resource #### Custom CA Certificates To add custom SSL certificates, add your `cacerts` file to `resources/oracle_jre/lib/security/cacerts`. This file will be overlayed onto the Oracle distribution. + ### Memory -The total available memory is specified when an application is pushed as part of it's configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials` and/or `stack_threads` mappings. +The total available memory for the application's container is specified when an application is pushed. +The Java buildpack uses this value to control the JRE's use of various +regions of memory and logs the JRE memory settings when the application starts or restarts. +These settings can be influenced by configuring +the `stack_threads` and/or `class_count` mappings (both part of the `memory_calculator` mapping), +and/or Java options relating to memory. Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. -Note: If setting an initial Stack size, depending on the version of Java and the operating system used by Cloud Foundry the JRE will require a minimum `-Xss` value. This tends to be between `100k` and `250k`. - -#### Memory Sizes -The following optional properties may be specified in the `memory_sizes` mapping. - -| Name | Description -| ---- | ----------- -| `heap` | The maximum heap size to use. It may be a single value such as `64m` or a range of acceptable values such as `128m..256m`. It is used to calculate the value of the Java command line options `-Xmx` and `-Xms`. -| `metaspace` | The maximum Metaspace size to use. It is applicable to versions of Oracle from 1.8 onwards. It may be a single value such as `64m` or a range of acceptable values such as `128m..256m`. It is used to calculate the value of the Java command line options `-XX:MaxMetaspaceSize=` and `-XX:MetaspaceSize=`. -| `native` | The amount of memory to reserve for native memory allocation. It should normally be omitted or specified as a range with no upper bound such as `100m..`. It does not correspond to a switch on the Java command line. -| `permgen` | The maximum PermGen size to use. It is applicable to versions of Oracle earlier than 1.8. It may be a single value such as `64m` or a range of acceptable values such as `128m..256m`. It is used to calculate the value of the Java command line options `-XX:MaxPermSize=` and `-XX:PermSize=`. -| `stack` | The stack size to use. It may be a single value such as `2m` or a range of acceptable values such as `2m..4m`. It is used to calculate the value of the Java command line option `-Xss`. - -Memory sizes together with _memory weightings_ (described in the next section) are used to calculate the amount of memory for each memory type. The calculation is described later. - -Memory sizes consist of a non-negative integer followed by a unit (`k` for kilobytes, `m` for megabytes, `g` for gigabytes; the case is not significant). Only the memory size `0` may be specified without a unit. +#### Total Memory -The above memory size properties may be omitted with an empty value, specified as a single value, or specified as a range. Ranges use the syntax `..`, although either bound may be omitted in which case the defaults of zero and the total available memory are used for the lower bound and upper bound, respectively. Examples of ranges are `100m..200m` (any value between 100 and 200 megabytes, inclusive) and `100m..` (any value greater than or equal to 100 megabytes). +The user can change the container's total memory available to influence the JRE memory settings. +Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory +available results in the heap size setting increasing or decreasing by a corresponding amount. -Each form of memory size is equivalent to a range. Omitting a memory size is equivalent to specifying the range `0..`. Specifying a single value is equivalent to specifying the range with that value as both the lower and upper bound, for example `128m` is equivalent to the range `128m..128m`. +#### Stack Threads -#### Memory Weightings -Memory weightings are configured in the `memory_heuristics` mapping of [`config/oracle_jre.yml`][]. Each weighting is a non-negative number and represents a proportion of the total available memory (represented by the sum of all the weightings). For example, the following weightings: +The amount of memory that should be allocated to stacks is given as an amount of memory per +thread with the Java option `-Xss`. If an explicit number of +threads should be used for the calculation of stack memory, then it should be specified as in +the following example: ```yaml -memory_heuristics: - heap: 15 - native: 2 - permgen: 5 - stack: 1 +stack_threads: 500 ``` -represent a maximum heap size three times as large as the maximum PermGen size, and so on. - -Memory weightings are used together with memory ranges to calculate the amount of memory for each memory type, as follows. +#### Loaded Classes -#### Memory Initials -Memory initials are configured in the `memory_initials` mapping of [`config/oracle_jre.yml`][]. Each initial is a percentage of the given type of memory. Valid memory types are `heap`, `permgen`, and `metaspace`. For example, the following initials: +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: ```yaml -memory_initials: - heap: 50% - permgen: 25% +class_count: 500 ``` -Given a maximum heap (Xmx) of 1G and a maximum permgen (-XX:MaxPermsize) of 256M an initial heap (Xms) of 512M and an initial permgen (-XX:Permsize) of 64M would be used. +#### Java Options -If no initial value is specified for a memory type the JVM default will be used. - -A value of 100% for each memory types is generally recommended for best performance. Smaller values will potentially preserve unused system memory for other tenants on the same host. Using the G1 garbage collector along with aggressive `MinHeapFreeRatio` and `MaxHeapFreeRatio` values the JVM will actually release unused heap back to the system up to the initial value. - -#### Stack Threads - -The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory then it should be specified like the following example: - -```yaml -stack_threads: 500 -``` +If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to +specific values. The heap size can be set explicitly, but changing the value of options other +than the heap size can also affect the heap size. For example, if the user increases +the maximum direct memory size from its default value of 10 Mb to 20 Mb, then this will +reduce the calculated heap size by 10 Mb. #### Memory Calculation Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. -The total available memory is allocated into heap, Metaspace or PermGen (depending on the version of Oracle), stack, and native memory types. +The container's total available memory is allocated into heap, metaspace and compressed class space (or permanent generation for Java 7), +direct memory, and stack memory settings. + +The memory calculation is described in more detail in the [Memory Calculator's README]. + +The inputs to the memory calculation, except the container's total memory (which is unknown at staging time), are logged during staging, for example: +``` +Loaded Classes: 13974, Threads: 300, JAVA_OPTS: '' +``` -The total available memory is first allocated to each memory type in proportion to its weighting (this is called ‘balancing'). If the resultant size of any memory type lies outside its range, the size is constrained to the range, the constrained size is excluded from the remaining memory, and no further calculation is required for that memory type. The remaining memory is then balanced against the memory types that are left, and the check is repeated until no calculated memory sizes lie outside their ranges. The remaining memory is then allocated to the remaining memory types according to the last balance step. This iteration terminates when none of the sizes of the remaining memory types is constrained by their corresponding ranges. +The container's total memory is logged during `cf push` and `cf scale`, for example: +``` + state since cpu memory disk details +#0 running 2017-04-10 02:20:03 PM 0.0% 896K of 1G 1.3M of 1G +``` -Termination is guaranteed since there is a finite number of memory types and in each iteration either none of the remaining memory sizes is constrained by the corresponding range and allocation terminates or at least one memory size is constrained by the corresponding range and is omitted from the next iteration. +The JRE memory settings are logged when the application is started or re-started, for example: +``` +JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199K \ + -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=18134K -Xss1M -Xmx368042K +``` [`config/components.yml`]: ../config/components.yml [`config/oracle_jre.yml`]: ../config/oracle_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [OpenJDK JRE]: jre-open_jdk_jre.md [Oracle]: http://www.oracle.com/technetwork/java/index.html [repositories]: extending-repositories.md diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index b81e1a3495..5e8f7f356a 100755 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -27,9 +27,7 @@ To use Zulu JRE instead of OpenJDK without forking java-buildpack, set environme | Name | Description | ---- | ----------- -| `memory_sizes` | Optional memory sizes, described under "Memory Sizes". -| `memory_heuristics` | Default memory size weightings, described under "Memory Weightings". -| `memory_initials` | Initial memory sizes, described under "Memory Initials". +| `memory_calculator` | Memory calculator defaults, described below under "Memory". | `repository_root` | The URL of the Zulu repository index ([details][repositories]). | `version` | The version of Java runtime to use. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. @@ -43,82 +41,79 @@ To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resource To add custom SSL certificates, add your `cacerts` file to `resources/zulu_jre/lib/security/cacerts`. This file will be overlayed onto the Zulu distribution. ### Memory -The total available memory is specified when an application is pushed as part of its configuration. The Java buildpack uses this value to control the JRE's use of various regions of memory. The JRE memory settings can be influenced by configuring the `memory_sizes`, `memory_heuristics`, `memory_initials`, and/or `stack_threads` mappings. +The total available memory for the application's container is specified when an application is pushed. +The Java buildpack uses this value to control the JRE's use of various +regions of memory and logs the JRE memory settings when the application starts or restarts. +These settings can be influenced by configuring +the `stack_threads` and/or `class_count` mappings (both part of the `memory_calculator` mapping), +and/or Java options relating to memory. -Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings next time the application is started. +Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. -Note: If setting an initial Stack size, depending on the version of Java and the operating system used by Cloud Foundry, the JRE will require a minimum `-Xss` value. This value tends to be between `100k` and `250k`. +#### Total Memory -#### Memory Sizes -The following optional properties may be specified in the `memory_sizes` mapping. +The user can change the container's total memory available to influence the JRE memory settings. +Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory +available results in the heap size setting increasing or decreasing by a corresponding amount. -| Name | Description -| ---- | ----------- -| `heap` | The maximum heap size to use. It may be a single value, such as `64m` or a range of acceptable values, such as `128m..256m`. It is used to calculate the value of the Java command-line options `-Xmx` and `-Xms`. -| `metaspace` | The maximum Metaspace size to use. It is applicable to versions of Zulu from Java 1.8 onwards. It may be a single value, such as `64m` or a range of acceptable values, such as `128m..256m`. It is used to calculate the value of the Java command-line options `-XX:MaxMetaspaceSize=` and `-XX:MetaspaceSize=`. -| `native` | The amount of memory to reserve for native memory allocation. It should normally be omitted or specified as a range with no upper bound such as `100m..`. It does not correspond to a switch on the Java command line. -| `permgen` | The maximum PermGen size to use. It is applicable to versions of Zulu earlier than Java 1.8. It may be a single value, such as `64m` or a range of acceptable values, such as `128m..256m`. It is used to calculate the value of the Java command-line options `-XX:MaxPermSize=` and `-XX:PermSize=`. -| `stack` | The stack size to use. It may be a single value, such as `2m` or a range of acceptable values, such as `2m..4m`. It is used to calculate the value of the Java command-line option `-Xss`. - -Memory sizes together with _memory weightings_ are used to calculate the amount of memory for each memory type. The calculation is described later. - -Memory sizes consist of a non-negative integer followed by a unit (`k` for kilobytes, `m` for megabytes, `g` for gigabytes; the case is not significant). Only the memory size `0` may be specified without a unit. - -The above memory size properties may be omitted with an empty value, specified as a single value, or specified as a range. Ranges use the syntax `..`, although either bound may be omitted in which case the defaults of zero and the total available memory are used for the lower bound and upper bound, respectively. Examples of ranges are `100m..200m` (any value between 100 and 200 megabytes, inclusive) and `100m..` (any value greater than or equal to 100 megabytes). - -Each form of memory size is equivalent to a range. Omitting a memory size is equivalent to specifying the range `0..`. Specifying a single value is equivalent to specifying the range with that value as both the lower and upper bound, for example `128m` is equivalent to the range `128m..128m`. +#### Stack Threads -#### Memory Weightings -Memory weightings are configured in the `memory_heuristics` mapping of [`config/zulu_jre.yml`][]. Each weighting is a non-negative number and represents a proportion of the total available memory (represented by the sum of all the weightings),- for example: +The amount of memory that should be allocated to stacks is given as an amount of memory per +thread with the Java option `-Xss`. If an explicit number of +threads should be used for the calculation of stack memory, then it should be specified as in +the following example: ```yaml -memory_heuristics: - heap: 15 - native: 2 - permgen: 5 - stack: 1 +stack_threads: 500 ``` -represent a maximum heap size three times as large as the maximum PermGen size, and so on. - -Memory weightings are used together with memory ranges to calculate the amount of memory for each memory type, as follows. +#### Loaded Classes -#### Memory Initials -Memory initials are configured in the `memory_initials` mapping of [`config/zulu_jre.yml`][]. Each initial is a percentage of the given type of memory. Valid memory types are `heap`, `permgen`, and `metaspace`. For example, the following initials: +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: ```yaml -memory_initials: - heap: 50% - permgen: 25% +class_count: 500 ``` -Given a maximum heap (`Xmx`) of 1G and a maximum permgen (`-XX:MaxPermsize`) of 256M an initial heap (`Xms`) of 512M and an initial permgen (`-XX:Permsize`) of 64M would be used. +#### Java Options -If no initial value is specified for a memory type, the JVM default will be used. +If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to +specific values. The heap size can be set explicitly, but changing the value of options other +than the heap size can also affect the heap size. For example, if the user increases +the maximum direct memory size from its default value of 10 Mb to 20 Mb, then this will +reduce the calculated heap size by 10 Mb. -A value of 100% for each memory types is generally recommended for best performance. Smaller values will potentially preserve unused system memory for other tenants on the same host. Using the G1 garbage collector along with aggressive `MinHeapFreeRatio` and `MaxHeapFreeRatio` values the JVM will actually release unused heap back to the system up to the initial value. - -#### Stack Threads +#### Memory Calculation +Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. -The amount of memory that should be allocated to the stack is given as an amount of memory per thread with the command-line option `-Xss`. The default behaviour is to use an estimate of the number of threads based on the total memory for the application. If an explicit number of threads should be used for the calculation of stack memory, then it should be specified like in the following example: +The container's total available memory is allocated into heap, metaspace and compressed class space (or permanent generation for Java 7), +direct memory, and stack memory settings. -```yaml -stack_threads: 500 +The memory calculation is described in more detail in the [Memory Calculator's README]. + +The inputs to the memory calculation, except the container's total memory (which is unknown at staging time), are logged during staging, for example: +``` +Loaded Classes: 13974, Threads: 300, JAVA_OPTS: '' ``` -#### Memory Calculation -Memory calculation happens before every `start` of an application and it is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. - -The total available memory is allocated into heap, Metaspace, or PermGen (depending on the version of Java), stack, and native memory types. - -The total available memory is first allocated to each memory type in proportion to its weighting (this is called 'balancing'). If the resultant size of any memory type lies outside its range, the size is constrained to the range, the constrained size is excluded from the remaining memory, and no further calculation is required for that memory type. The remaining memory is then balanced against the memory types that are left, and the check is repeated until no calculated memory sizes lie outside their ranges. The remaining memory is then allocated to the remaining memory types according to the last balance step. This iteration terminates when none of the sizes of the remaining memory types is constrained by their corresponding ranges. +The container's total memory is logged during `cf push` and `cf scale`, for example: +``` + state since cpu memory disk details +#0 running 2017-04-10 02:20:03 PM 0.0% 896K of 1G 1.3M of 1G +``` -Termination is guaranteed since there is a finite number of memory types and in each iteration either none of the remaining memory sizes is constrained by the corresponding range and allocation terminates or at least one memory size is constrained by the corresponding range and it is omitted from the next iteration. +The JRE memory settings are logged when the application is started or re-started, for example: +``` +JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199K \ + -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=18134K -Xss1M -Xmx368042K +``` [`config/components.yml`]: ../config/components.yml [`config/zulu_jre.yml`]: ../config/zulu_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [Zulu JRE]: jre-zulu_jre.md [Azul Zulu]: https://www.azul.com/products/zulu/ [repositories]: extending-repositories.md From c278a5d0829eabc11bf4cdbee003dcae6d257518 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 10 Apr 2017 14:03:09 -0700 Subject: [PATCH 260/812] Polishing --- config/app_dynamics_agent.yml | 4 ++-- config/tomcat.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index e2374bfd96..7129edc307 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -16,9 +16,9 @@ # Configuration for the AppDynamics framework --- version: 4.+ -repository_root: "https://packages.appdynamics.com/java" +repository_root: https://packages.appdynamics.com/java default_application_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); puts \"#{a['space_name']}:#{a['application_name']}\"") default_node_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); puts \"#{a['application_name']}:#{a['instance_index']}\"") -default_tier_name: +default_tier_name: diff --git a/config/tomcat.yml b/config/tomcat.yml index 17ef612d62..423fc0d97d 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -18,11 +18,11 @@ tomcat: version: 8.0.+ repository_root: "{default.repository.root}/tomcat" - context_path: + context_path: external_configuration_enabled: false external_configuration: version: 1.+ - repository_root: + repository_root: lifecycle_support: version: 2.+ repository_root: "{default.repository.root}/tomcat-lifecycle-support" From 0ffac1d1e681a5c639cc35f1d961001726cd331f Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 21 Apr 2017 15:24:40 -0700 Subject: [PATCH 261/812] Make JRE Source Optional Previously, the JRE source was both required and fixed to a location only available in the "normal" JRE. This caused an issue where the JRE source could not be found in its usual place (because it was a server JRE). This missing JRE source caused a staging failure. This change updates the logic to try the "normal" JRE location, then the server JRE location, and if neither are found to simply not add any JRE source at all, allowing staging to complete without integrating the JRE certificates. [resolves #415] --- .../container_certificate_trust_store.rb | 21 ++++++++--- .../container_certificate_trust_store_spec.rb | 37 +++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/framework/container_certificate_trust_store.rb b/lib/java_buildpack/framework/container_certificate_trust_store.rb index 8edcf8022e..b0f172970c 100644 --- a/lib/java_buildpack/framework/container_certificate_trust_store.rb +++ b/lib/java_buildpack/framework/container_certificate_trust_store.rb @@ -30,10 +30,7 @@ def compile with_timing("Adding certificates to #{trust_store.relative_path_from(@droplet.root)}") do FileUtils.mkdir_p trust_store.parent - - shell "#{java} -jar #{@droplet.sandbox + jar_name} --container-source #{ca_certificates} --destination " \ - "#{trust_store} --destination-password #{password} --jre-source #{cacerts} --jre-source-password " \ - 'changeit' + shell command end end @@ -68,18 +65,30 @@ def ca_certificates end end - def cacerts - @droplet.java_home.root + 'lib/security/cacerts' + def command + command = "#{java} -jar #{@droplet.sandbox + jar_name} --container-source #{ca_certificates} --destination " \ + "#{trust_store} --destination-password #{password}" + command += " --jre-source #{jre_cacerts} --jre-source-password changeit" if jre_cacerts.exist? + command += " --jre-source #{server_jre_cacerts} --jre-source-password changeit" if server_jre_cacerts.exist? + command end def java @droplet.java_home.root + 'bin/java' end + def jre_cacerts + @droplet.java_home.root + 'lib/security/cacerts' + end + def password 'java-buildpack-trust-store-password' end + def server_jre_cacerts + @droplet.java_home.root + 'jre/lib/security/cacerts' + end + def supports_configuration? @configuration['enabled'] end diff --git a/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb b/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb index a4f29bd8fd..c684ef2c5e 100644 --- a/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb +++ b/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb @@ -16,6 +16,7 @@ require 'spec_helper' require 'component_helper' +require 'fileutils' require 'java_buildpack/framework/container_certificate_trust_store' describe JavaBuildpack::Framework::ContainerCertificateTrustStore do @@ -44,6 +45,23 @@ it 'creates truststore', cache_fixture: 'stub-container-customizer.jar' do + allow(component).to receive(:ca_certificates).and_return(ca_certificates) + allow(component).to receive(:shell).with("#{java_home.root}/bin/java -jar " \ + "#{sandbox}/container_certificate_trust_store-0.0.0.jar " \ + "--container-source #{ca_certificates} " \ + "--destination #{sandbox}/truststore.jks " \ + '--destination-password java-buildpack-trust-store-password') + + component.compile + end + + it 'creates truststore with jre source', + cache_fixture: 'stub-container-customizer.jar' do + + cacerts = java_home.root + 'lib/security/cacerts' + FileUtils.mkdir_p(cacerts.parent) + FileUtils.touch(cacerts) + allow(component).to receive(:ca_certificates).and_return(ca_certificates) allow(component).to receive(:shell).with("#{java_home.root}/bin/java -jar " \ "#{sandbox}/container_certificate_trust_store-0.0.0.jar " \ @@ -56,6 +74,25 @@ component.compile end + it 'creates truststore with server jre source', + cache_fixture: 'stub-container-customizer.jar' do + + cacerts = java_home.root + 'jre/lib/security/cacerts' + FileUtils.mkdir_p(cacerts.parent) + FileUtils.touch(cacerts) + + allow(component).to receive(:ca_certificates).and_return(ca_certificates) + allow(component).to receive(:shell).with("#{java_home.root}/bin/java -jar " \ + "#{sandbox}/container_certificate_trust_store-0.0.0.jar " \ + "--container-source #{ca_certificates} " \ + "--destination #{sandbox}/truststore.jks " \ + '--destination-password java-buildpack-trust-store-password ' \ + "--jre-source #{java_home.root}/jre/lib/security/cacerts " \ + '--jre-source-password changeit') + + component.compile + end + it 'adds truststore properties' do component.release expect(java_opts).to include('-Djavax.net.ssl.trustStore=$PWD/.java-buildpack/container_certificate_trust_store/' \ From 67863bf98a941ab75e76cf965ffc84cade0e8f84 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 26 Apr 2017 13:48:39 -0700 Subject: [PATCH 262/812] Ruby Version Updates --- ci/docker-image/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 8f5ebd9d0f..091cec3399 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -30,10 +30,10 @@ RUN eval "$(rbenv init -)" \ && echo 'bundler' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ - && rbenv install 2.2.6 + && rbenv install 2.2.7 RUN eval "$(rbenv init -)" \ - && rbenv install 2.3.3 + && rbenv install 2.3.4 RUN eval "$(rbenv init -)" \ && rbenv install 2.4.1 From a9ddbfb3bcc97e12c4e995bd5e6ca6c7e145d65a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 26 Apr 2017 15:25:16 -0700 Subject: [PATCH 263/812] Dependency Updates This change updates the dependencies in the buildpack. It also makes all changes required by the upgrade to Rubocop. --- .idea/inspectionProfiles/Project_Default.xml | 2 +- .idea/misc.xml | 2 +- .rubocop.yml | 3 ++ .ruby-version | 2 +- Gemfile.lock | 17 +++--- Rakefile | 3 +- bin/compile | 1 - bin/detect | 1 - bin/release | 1 - java-buildpack.iml | 54 +++++++++---------- lib/java_buildpack.rb | 1 - lib/java_buildpack/buildpack.rb | 1 - lib/java_buildpack/buildpack_version.rb | 1 - lib/java_buildpack/component.rb | 1 - .../component/additional_libraries.rb | 1 - lib/java_buildpack/component/application.rb | 1 - .../component/base_component.rb | 1 - lib/java_buildpack/component/droplet.rb | 1 - .../component/environment_variables.rb | 1 - .../component/immutable_java_home.rb | 1 - lib/java_buildpack/component/java_opts.rb | 1 - .../component/modular_component.rb | 1 - .../component/mutable_java_home.rb | 1 - lib/java_buildpack/component/services.rb | 1 - .../versioned_dependency_component.rb | 1 - lib/java_buildpack/container.rb | 1 - lib/java_buildpack/container/dist_zip.rb | 1 - lib/java_buildpack/container/dist_zip_like.rb | 1 - lib/java_buildpack/container/groovy.rb | 1 - lib/java_buildpack/container/java_main.rb | 1 - .../container/play_framework.rb | 1 - lib/java_buildpack/container/ratpack.rb | 1 - lib/java_buildpack/container/spring_boot.rb | 1 - .../container/spring_boot_cli.rb | 1 - lib/java_buildpack/container/tomcat.rb | 1 - .../tomcat/tomcat_access_logging_support.rb | 1 - .../tomcat/tomcat_external_configuration.rb | 1 - .../tomcat/tomcat_insight_support.rb | 1 - .../container/tomcat/tomcat_instance.rb | 1 - .../tomcat/tomcat_lifecycle_support.rb | 1 - .../tomcat/tomcat_logging_support.rb | 1 - .../container/tomcat/tomcat_redis_store.rb | 1 - .../container/tomcat/tomcat_utils.rb | 1 - lib/java_buildpack/framework.rb | 1 - .../framework/app_dynamics_agent.rb | 1 - .../container_certificate_trust_store.rb | 1 - .../framework/container_customizer.rb | 1 - lib/java_buildpack/framework/debug.rb | 1 - .../framework/dyadic_ekm_security_provider.rb | 1 - .../framework/dynatrace_appmon_agent.rb | 1 - .../framework/dynatrace_one_agent.rb | 1 - .../framework/google_stackdriver_debugger.rb | 1 - .../framework/introscope_agent.rb | 1 - lib/java_buildpack/framework/java_opts.rb | 1 - lib/java_buildpack/framework/jmx.rb | 1 - lib/java_buildpack/framework/jrebel_agent.rb | 1 - .../framework/luna_security_provider.rb | 1 - lib/java_buildpack/framework/maria_db_jdbc.rb | 3 +- .../framework/new_relic_agent.rb | 1 - .../play_framework_auto_reconfiguration.rb | 1 - .../framework/play_framework_jpa_plugin.rb | 1 - .../framework/postgresql_jdbc.rb | 1 - .../protect_app_security_provider.rb | 1 - .../framework/spring_auto_reconfiguration.rb | 1 - .../web_xml_modifier.rb | 5 +- .../framework/spring_insight.rb | 1 - .../framework/your_kit_profiler.rb | 1 - lib/java_buildpack/jre.rb | 1 - lib/java_buildpack/jre/open_jdk_jre.rb | 1 - lib/java_buildpack/jre/open_jdk_like.rb | 1 - lib/java_buildpack/jre/open_jdk_like_jre.rb | 1 - .../jre/open_jdk_like_memory_calculator.rb | 1 - lib/java_buildpack/jre/oracle_jre.rb | 1 - lib/java_buildpack/jre/zulu_jre.rb | 1 - lib/java_buildpack/logging.rb | 1 - .../logging/delegating_logger.rb | 1 - lib/java_buildpack/logging/logger_factory.rb | 1 - lib/java_buildpack/repository.rb | 1 - .../repository/configured_item.rb | 1 - .../repository/repository_index.rb | 1 - .../repository/version_resolver.rb | 1 - lib/java_buildpack/util.rb | 1 - lib/java_buildpack/util/cache.rb | 1 - .../util/cache/application_cache.rb | 1 - lib/java_buildpack/util/cache/cached_file.rb | 1 - .../util/cache/download_cache.rb | 3 +- .../util/cache/inferred_network_failure.rb | 1 - .../util/cache/internet_availability.rb | 1 - lib/java_buildpack/util/class_file_utils.rb | 1 - .../util/configuration_utils.rb | 1 - lib/java_buildpack/util/constantize.rb | 1 - lib/java_buildpack/util/dash_case.rb | 1 - lib/java_buildpack/util/file_enumerable.rb | 1 - lib/java_buildpack/util/filtering_pathname.rb | 5 +- .../util/find_single_directory.rb | 1 - lib/java_buildpack/util/format_duration.rb | 1 - lib/java_buildpack/util/groovy_utils.rb | 1 - lib/java_buildpack/util/jar_finder.rb | 1 - lib/java_buildpack/util/java_main_utils.rb | 1 - lib/java_buildpack/util/play.rb | 1 - lib/java_buildpack/util/play/base.rb | 1 - lib/java_buildpack/util/play/factory.rb | 1 - lib/java_buildpack/util/play/post22.rb | 1 - lib/java_buildpack/util/play/post22_dist.rb | 1 - lib/java_buildpack/util/play/post22_staged.rb | 1 - lib/java_buildpack/util/play/pre22.rb | 1 - lib/java_buildpack/util/play/pre22_dist.rb | 1 - lib/java_buildpack/util/play/pre22_staged.rb | 1 - lib/java_buildpack/util/properties.rb | 1 - lib/java_buildpack/util/qualify_path.rb | 1 - lib/java_buildpack/util/ratpack_utils.rb | 1 - lib/java_buildpack/util/sanitizer.rb | 1 - lib/java_buildpack/util/shell.rb | 1 - lib/java_buildpack/util/snake_case.rb | 1 - lib/java_buildpack/util/space_case.rb | 1 - lib/java_buildpack/util/spring_boot_utils.rb | 1 - lib/java_buildpack/util/start_script.rb | 1 - lib/java_buildpack/util/to_b.rb | 1 - lib/java_buildpack/util/tokenized_version.rb | 1 - rakelib/dependency_cache_task.rb | 1 - rakelib/package.rb | 5 +- rakelib/package_task.rb | 1 - rakelib/stage_buildpack_task.rb | 1 - resources/open_jdk_jre/bin/killjava.sh | 1 - resources/oracle_jre/bin/killjava.sh | 1 - resources/zulu_jre/bin/killjava.sh | 1 - spec/application_helper.rb | 1 - spec/bin/compile_spec.rb | 1 - spec/bin/detect_spec.rb | 1 - spec/bin/release_spec.rb | 1 - spec/component_helper.rb | 1 - spec/console_helper.rb | 1 - spec/droplet_helper.rb | 7 ++- .../container/long_detect_tags.rb | 1 - spec/integration_helper.rb | 3 +- spec/internet_availability_helper.rb | 1 - spec/java_buildpack/buildpack_spec.rb | 1 - spec/java_buildpack/buildpack_version_spec.rb | 1 - .../component/additional_libraries_spec.rb | 1 - .../component/application_spec.rb | 1 - .../component/base_component_spec.rb | 1 - spec/java_buildpack/component/droplet_spec.rb | 1 - .../component/environment_variables_spec.rb | 1 - .../component/immutable_java_home_spec.rb | 3 +- .../component/java_opts_spec.rb | 1 - .../component/modular_component_spec.rb | 1 - .../component/mutable_java_home_spec.rb | 1 - .../java_buildpack/component/services_spec.rb | 13 +++-- .../versioned_dependency_component_spec.rb | 1 - .../container/dist_zip_like_spec.rb | 1 - .../java_buildpack/container/dist_zip_spec.rb | 1 - spec/java_buildpack/container/groovy_spec.rb | 1 - .../container/java_main_spec.rb | 1 - .../container/play_framework_spec.rb | 1 - spec/java_buildpack/container/ratpack_spec.rb | 1 - .../container/spring_boot_cli_spec.rb | 1 - .../container/spring_boot_spec.rb | 1 - .../tomcat_access_logging_support_spec.rb | 1 - .../tomcat_external_configuration_spec.rb | 1 - .../tomcat/tomcat_insight_support_spec.rb | 1 - .../container/tomcat/tomcat_instance_spec.rb | 1 - .../tomcat/tomcat_lifecycle_support_spec.rb | 1 - .../tomcat/tomcat_logging_support_spec.rb | 1 - .../tomcat/tomcat_redis_store_spec.rb | 5 +- spec/java_buildpack/container/tomcat_spec.rb | 1 - .../framework/app_dynamics_agent_spec.rb | 1 - .../container_certificate_trust_store_spec.rb | 1 - .../framework/container_customizer_spec.rb | 1 - spec/java_buildpack/framework/debug_spec.rb | 1 - .../dyadic_ekm_security_provider_spec.rb | 1 - .../framework/dynatrace_appmon_agent_spec.rb | 1 - .../framework/dynatrace_one_agent_spec.rb | 5 +- .../google_stackdriver_debugger_spec.rb | 1 - .../framework/introscope_agent_spec.rb | 3 +- .../framework/java_opts_spec.rb | 1 - spec/java_buildpack/framework/jmx_spec.rb | 1 - .../framework/jrebel_agent_spec.rb | 1 - .../framework/luna_security_provider_spec.rb | 5 +- .../framework/maria_db_jdbc_spec.rb | 1 - .../framework/new_relic_agent_spec.rb | 3 +- ...lay_framework_auto_reconfiguration_spec.rb | 1 - .../play_framework_jpa_plugin_spec.rb | 1 - .../framework/postgresql_jdbc_spec.rb | 1 - .../protect_app_security_provider_spec.rb | 1 - .../web_xml_modifier_spec.rb | 1 - .../spring_auto_reconfiguration_spec.rb | 1 - .../framework/spring_insight_spec.rb | 1 - .../framework/your_kit_profiler_spec.rb | 1 - .../jre/open_jdk_like_jre_spec.rb | 1 - .../open_jdk_like_memory_calculator_spec.rb | 1 - spec/java_buildpack/jre/open_jdk_like_spec.rb | 1 - .../logging/delegating_logger_spec.rb | 1 - .../logging/logger_factory_spec.rb | 1 - .../repository/configured_item_spec.rb | 1 - .../repository/repository_index_spec.rb | 9 ++-- .../repository/version_resolver_spec.rb | 3 +- .../util/cache/application_cache_spec.rb | 1 - .../util/cache/cached_file_spec.rb | 7 ++- .../util/cache/download_cache_spec.rb | 1 - .../util/cache/internet_availability_spec.rb | 1 - .../util/cache/yield_file_with_content.rb | 1 - .../util/configuration_utils_spec.rb | 1 - spec/java_buildpack/util/constantize_spec.rb | 1 - .../util/filtering_pathname_spec.rb | 1 - .../util/format_duration_spec.rb | 1 - .../util/java_main_utils_spec.rb | 1 - spec/java_buildpack/util/play/base_spec.rb | 1 - spec/java_buildpack/util/play/factory_spec.rb | 1 - .../util/play/post22_dist_spec.rb | 1 - spec/java_buildpack/util/play/post22_spec.rb | 1 - .../util/play/post22_staged_spec.rb | 1 - .../util/play/pre22_dist_spec.rb | 1 - spec/java_buildpack/util/play/pre22_spec.rb | 1 - .../util/play/pre22_staged_spec.rb | 1 - spec/java_buildpack/util/properties_spec.rb | 1 - .../java_buildpack/util/ratpack_utils_spec.rb | 1 - spec/java_buildpack/util/sanitize_spec.rb | 1 - spec/java_buildpack/util/shell_spec.rb | 1 - .../util/spring_boot_utils_spec.rb | 1 - .../util/tokenized_version_spec.rb | 1 - spec/logging_helper.rb | 1 - spec/memory_limit_helper.rb | 1 - spec/spec_helper.rb | 1 - 223 files changed, 78 insertions(+), 291 deletions(-) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index e32723892f..48eede57c8 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index ee819f1d8b..acd064c15c 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,5 +4,5 @@ - + \ No newline at end of file diff --git a/.rubocop.yml b/.rubocop.yml index 9fe2b8978e..88ddc6301a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,6 +7,7 @@ AllCops: - 'rakelib/**/*' Exclude: - 'build/**/*' + - Gemfile # TODO: Remove when upgrading to any version after 0.48.1 Metrics/AbcSize: Max: 22 Metrics/BlockLength: @@ -45,6 +46,8 @@ Style/EmptyLinesAroundClassBody: Enabled: false Style/EmptyLinesAroundModuleBody: Enabled: false +Style/IndentHeredoc: # TODO: Remove when dropping 2.2.x support + Enabled: false Style/MethodMissing: Enabled: false Style/MultilineOperationIndentation: diff --git a/.ruby-version b/.ruby-version index bda8fbec15..5bc1cc43d4 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.2.6 +2.2.7 diff --git a/Gemfile.lock b/Gemfile.lock index 229ae31083..4260ce570b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.5.0) + addressable (2.5.1) public_suffix (~> 2.0, >= 2.0.2) ast (2.3.0) crack (0.4.3) @@ -12,7 +12,8 @@ GEM ast (~> 2.2) powerpack (0.1.1) public_suffix (2.0.5) - rainbow (2.2.1) + rainbow (2.2.2) + rake rake (12.0.0) redcarpet (3.4.0) rspec (3.5.0) @@ -28,24 +29,24 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.5.0) rspec-support (3.5.0) - rubocop (0.47.1) + rubocop (0.48.1) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.12.0) + rubocop-rspec (1.15.0) rubocop (>= 0.42.0) ruby-progressbar (1.8.1) rubyzip (1.2.1) safe_yaml (1.0.4) tee (1.0.0) - unicode-display_width (1.1.3) - webmock (2.3.2) + unicode-display_width (1.2.1) + webmock (3.0.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - yard (0.9.8) + yard (0.9.9) PLATFORMS ruby @@ -62,4 +63,4 @@ DEPENDENCIES yard BUNDLED WITH - 1.14.5 + 1.14.6 diff --git a/Rakefile b/Rakefile index 8d163f9c06..cfce5f0dcc 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -42,4 +41,4 @@ Package::StageBuildpackTask.new(Dir['bin/**/*', 'config/**/*', 'lib/**/*', 'reso .reject { |f| File.directory? f }) Package::PackageTask.new -task default: %w(rubocop check_api_doc spec) +task default: %w[rubocop check_api_doc spec] diff --git a/bin/compile b/bin/compile index f2577ff24b..eb481cfe9e 100755 --- a/bin/compile +++ b/bin/compile @@ -1,5 +1,4 @@ #!/usr/bin/env ruby -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/bin/detect b/bin/detect index 56193192f4..9f4dd76d50 100755 --- a/bin/detect +++ b/bin/detect @@ -1,5 +1,4 @@ #!/usr/bin/env ruby -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/bin/release b/bin/release index 97e84b7c36..9b9dad0427 100755 --- a/bin/release +++ b/bin/release @@ -1,5 +1,4 @@ #!/usr/bin/env ruby -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/java-buildpack.iml b/java-buildpack.iml index a67d4ab86d..857eeecdf5 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -265,34 +265,34 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/java_buildpack.rb b/lib/java_buildpack.rb index dfefdcadc0..e74cba26c4 100644 --- a/lib/java_buildpack.rb +++ b/lib/java_buildpack.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 6970646f7b..4373d14dd6 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index c9d42fc6c4..cab64e96c7 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component.rb b/lib/java_buildpack/component.rb index 5f60f1af67..8a409fcaff 100644 --- a/lib/java_buildpack/component.rb +++ b/lib/java_buildpack/component.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/additional_libraries.rb b/lib/java_buildpack/component/additional_libraries.rb index 7b1c96fb30..08307d0abd 100644 --- a/lib/java_buildpack/component/additional_libraries.rb +++ b/lib/java_buildpack/component/additional_libraries.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index 5cd5d1f0f1..8f1867eb03 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 1d8e5ebb23..719f231ce5 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index c5174d6415..b47a89e74d 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/environment_variables.rb b/lib/java_buildpack/component/environment_variables.rb index 38fca4b920..9a1da704a1 100644 --- a/lib/java_buildpack/component/environment_variables.rb +++ b/lib/java_buildpack/component/environment_variables.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index 07b2226636..f281cee47b 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index d51996677b..ab85d586fc 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/modular_component.rb b/lib/java_buildpack/component/modular_component.rb index ecef3f5b0b..c738ee916a 100644 --- a/lib/java_buildpack/component/modular_component.rb +++ b/lib/java_buildpack/component/modular_component.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index c9e89b7b05..1df795e875 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/services.rb b/lib/java_buildpack/component/services.rb index b5728b1cf1..af77a462fb 100644 --- a/lib/java_buildpack/component/services.rb +++ b/lib/java_buildpack/component/services.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/versioned_dependency_component.rb b/lib/java_buildpack/component/versioned_dependency_component.rb index 935cd183b5..796043d991 100644 --- a/lib/java_buildpack/component/versioned_dependency_component.rb +++ b/lib/java_buildpack/component/versioned_dependency_component.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container.rb b/lib/java_buildpack/container.rb index 81d9316842..9fc8136888 100644 --- a/lib/java_buildpack/container.rb +++ b/lib/java_buildpack/container.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/dist_zip.rb b/lib/java_buildpack/container/dist_zip.rb index 4822e872fa..34546db5fa 100644 --- a/lib/java_buildpack/container/dist_zip.rb +++ b/lib/java_buildpack/container/dist_zip.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 9f35b4af43..599169b425 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index 5b11f75775..e02189dd90 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index bf9e2f7a42..dd14d95383 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/play_framework.rb b/lib/java_buildpack/container/play_framework.rb index 85117b9b72..4639b9d277 100644 --- a/lib/java_buildpack/container/play_framework.rb +++ b/lib/java_buildpack/container/play_framework.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/ratpack.rb b/lib/java_buildpack/container/ratpack.rb index 6d17366b1f..4ac829ca99 100644 --- a/lib/java_buildpack/container/ratpack.rb +++ b/lib/java_buildpack/container/ratpack.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/spring_boot.rb b/lib/java_buildpack/container/spring_boot.rb index 2ce4b12f34..074b13b4e8 100644 --- a/lib/java_buildpack/container/spring_boot.rb +++ b/lib/java_buildpack/container/spring_boot.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index a529c32216..2b745b3ba3 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index f4a1fbb703..e81475b89a 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb index 7ac7df0403..94fe74a60c 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb index 8ad5492058..8f33a1f7c7 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb index 6c306e185b..bae6e8c787 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index 90b2af251d..1406f53a46 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb index b86d12e6d6..156a64ed67 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb index 2490a4f1dc..393fb1d380 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb index 830bbc990d..a1eb8a74da 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_utils.rb b/lib/java_buildpack/container/tomcat/tomcat_utils.rb index 7f09c62081..732dd9aebc 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_utils.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_utils.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework.rb b/lib/java_buildpack/framework.rb index 6e85a805bb..24cc162ef1 100644 --- a/lib/java_buildpack/framework.rb +++ b/lib/java_buildpack/framework.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 58e76c2f88..c39b317510 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/container_certificate_trust_store.rb b/lib/java_buildpack/framework/container_certificate_trust_store.rb index b0f172970c..97d5915af7 100644 --- a/lib/java_buildpack/framework/container_certificate_trust_store.rb +++ b/lib/java_buildpack/framework/container_certificate_trust_store.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/container_customizer.rb b/lib/java_buildpack/framework/container_customizer.rb index fb6717f60a..1d50596a98 100644 --- a/lib/java_buildpack/framework/container_customizer.rb +++ b/lib/java_buildpack/framework/container_customizer.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index 36915a6746..9d236036dc 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index 99370ddff8..a768a8a1ce 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb index e0895460dc..a8a2034273 100644 --- a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 8e88f47c77..0f19f131b1 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/google_stackdriver_debugger.rb b/lib/java_buildpack/framework/google_stackdriver_debugger.rb index 7a0fc1252f..0045462420 100644 --- a/lib/java_buildpack/framework/google_stackdriver_debugger.rb +++ b/lib/java_buildpack/framework/google_stackdriver_debugger.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index 6b9e89ba6a..a92c479836 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index efa15c433f..c72a911360 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index b798f1a6cd..d2fa86d12d 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index 5e599a2015..9e7a4b9049 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index b506585eba..8864d6b31b 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/maria_db_jdbc.rb b/lib/java_buildpack/framework/maria_db_jdbc.rb index 7bc33b7784..ad4f8f5ebb 100644 --- a/lib/java_buildpack/framework/maria_db_jdbc.rb +++ b/lib/java_buildpack/framework/maria_db_jdbc.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -45,7 +44,7 @@ def supports? private def driver? - %w(mariadb-java-client*.jar mysql-connector-java*.jar).any? do |candidate| + %w[mariadb-java-client*.jar mysql-connector-java*.jar].any? do |candidate| (@application.root + '**' + candidate).glob.any? end end diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 1a4039ce50..477db07e0a 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb b/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb index 9bc04aedca..6437d54d69 100644 --- a/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/play_framework_jpa_plugin.rb b/lib/java_buildpack/framework/play_framework_jpa_plugin.rb index c0b8c10466..0da10eee5a 100644 --- a/lib/java_buildpack/framework/play_framework_jpa_plugin.rb +++ b/lib/java_buildpack/framework/play_framework_jpa_plugin.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/postgresql_jdbc.rb b/lib/java_buildpack/framework/postgresql_jdbc.rb index a26a884a39..cb03a38aab 100644 --- a/lib/java_buildpack/framework/postgresql_jdbc.rb +++ b/lib/java_buildpack/framework/postgresql_jdbc.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb index ce0c2fd5ed..4e308bacbd 100644 --- a/lib/java_buildpack/framework/protect_app_security_provider.rb +++ b/lib/java_buildpack/framework/protect_app_security_provider.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2016 the original author or authors. # diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 3bcccfb9ba..164ab2bb7b 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb index e12c1ac35d..7fd9928a2c 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -66,11 +65,11 @@ def to_s private - CONTEXT_INITIALIZER_ADDITIONAL = %w( + CONTEXT_INITIALIZER_ADDITIONAL = %w[ org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer - ).freeze + ].freeze CONTEXT_INITIALIZER_CLASSES = 'contextInitializerClasses'.freeze diff --git a/lib/java_buildpack/framework/spring_insight.rb b/lib/java_buildpack/framework/spring_insight.rb index 471b5da6be..4dbc081399 100644 --- a/lib/java_buildpack/framework/spring_insight.rb +++ b/lib/java_buildpack/framework/spring_insight.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/your_kit_profiler.rb b/lib/java_buildpack/framework/your_kit_profiler.rb index 7471c73fc7..9f4f04659c 100644 --- a/lib/java_buildpack/framework/your_kit_profiler.rb +++ b/lib/java_buildpack/framework/your_kit_profiler.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/jre.rb b/lib/java_buildpack/jre.rb index c7c57e93de..6134708789 100644 --- a/lib/java_buildpack/jre.rb +++ b/lib/java_buildpack/jre.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/jre/open_jdk_jre.rb b/lib/java_buildpack/jre/open_jdk_jre.rb index 510e4e8c48..e7a9cf202e 100644 --- a/lib/java_buildpack/jre/open_jdk_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_jre.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/jre/open_jdk_like.rb b/lib/java_buildpack/jre/open_jdk_like.rb index a8b48a3468..9f3f525238 100644 --- a/lib/java_buildpack/jre/open_jdk_like.rb +++ b/lib/java_buildpack/jre/open_jdk_like.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index b6d907eb91..b4c7461d40 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 642243728e..6e83feb9a9 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/jre/oracle_jre.rb b/lib/java_buildpack/jre/oracle_jre.rb index b6c9de253c..90a2d9bdde 100644 --- a/lib/java_buildpack/jre/oracle_jre.rb +++ b/lib/java_buildpack/jre/oracle_jre.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/jre/zulu_jre.rb b/lib/java_buildpack/jre/zulu_jre.rb index 5b8464ac45..213a3544d5 100755 --- a/lib/java_buildpack/jre/zulu_jre.rb +++ b/lib/java_buildpack/jre/zulu_jre.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2016 the original author or authors. # diff --git a/lib/java_buildpack/logging.rb b/lib/java_buildpack/logging.rb index e489f9eeeb..af137d973b 100644 --- a/lib/java_buildpack/logging.rb +++ b/lib/java_buildpack/logging.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/logging/delegating_logger.rb b/lib/java_buildpack/logging/delegating_logger.rb index 5d3ff00b50..e7662689a9 100644 --- a/lib/java_buildpack/logging/delegating_logger.rb +++ b/lib/java_buildpack/logging/delegating_logger.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/logging/logger_factory.rb b/lib/java_buildpack/logging/logger_factory.rb index f4cedc9552..38895a7d8e 100644 --- a/lib/java_buildpack/logging/logger_factory.rb +++ b/lib/java_buildpack/logging/logger_factory.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/repository.rb b/lib/java_buildpack/repository.rb index 2dec8e9f37..34c68780dd 100644 --- a/lib/java_buildpack/repository.rb +++ b/lib/java_buildpack/repository.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/repository/configured_item.rb b/lib/java_buildpack/repository/configured_item.rb index a54784604e..9a5f08cf80 100644 --- a/lib/java_buildpack/repository/configured_item.rb +++ b/lib/java_buildpack/repository/configured_item.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 5c8e56860b..192b79d0cc 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/repository/version_resolver.rb b/lib/java_buildpack/repository/version_resolver.rb index a833e3863b..b8210312d2 100644 --- a/lib/java_buildpack/repository/version_resolver.rb +++ b/lib/java_buildpack/repository/version_resolver.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util.rb b/lib/java_buildpack/util.rb index e1bde1fb5d..a01998ec31 100644 --- a/lib/java_buildpack/util.rb +++ b/lib/java_buildpack/util.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/cache.rb b/lib/java_buildpack/util/cache.rb index 56f2e1c60c..5192624ab3 100644 --- a/lib/java_buildpack/util/cache.rb +++ b/lib/java_buildpack/util/cache.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/cache/application_cache.rb b/lib/java_buildpack/util/cache/application_cache.rb index 57c7d0cae1..24d55f31c3 100644 --- a/lib/java_buildpack/util/cache/application_cache.rb +++ b/lib/java_buildpack/util/cache/application_cache.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/cache/cached_file.rb b/lib/java_buildpack/util/cache/cached_file.rb index 2ee16031af..966ed23b0d 100644 --- a/lib/java_buildpack/util/cache/cached_file.rb +++ b/lib/java_buildpack/util/cache/cached_file.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 121712800a..96fee72b1f 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -215,7 +214,7 @@ def client_authentication(http_options) end def compressed?(response) - %w(br compress deflate gzip x-gzip).include?(response['Content-Encoding']) + %w[br compress deflate gzip x-gzip].include?(response['Content-Encoding']) end def debug_ssl(http) diff --git a/lib/java_buildpack/util/cache/inferred_network_failure.rb b/lib/java_buildpack/util/cache/inferred_network_failure.rb index 9e4616675b..2623391c92 100644 --- a/lib/java_buildpack/util/cache/inferred_network_failure.rb +++ b/lib/java_buildpack/util/cache/inferred_network_failure.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/cache/internet_availability.rb b/lib/java_buildpack/util/cache/internet_availability.rb index 46ae640104..63ca075cc7 100644 --- a/lib/java_buildpack/util/cache/internet_availability.rb +++ b/lib/java_buildpack/util/cache/internet_availability.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/class_file_utils.rb b/lib/java_buildpack/util/class_file_utils.rb index b097f7ce4c..8014de2b25 100644 --- a/lib/java_buildpack/util/class_file_utils.rb +++ b/lib/java_buildpack/util/class_file_utils.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 27b0c8df55..a8fb66fe97 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/constantize.rb b/lib/java_buildpack/util/constantize.rb index 2ee6beb269..3bfd12b2e4 100644 --- a/lib/java_buildpack/util/constantize.rb +++ b/lib/java_buildpack/util/constantize.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/dash_case.rb b/lib/java_buildpack/util/dash_case.rb index 54c9e92952..8ed6bcfae0 100644 --- a/lib/java_buildpack/util/dash_case.rb +++ b/lib/java_buildpack/util/dash_case.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/file_enumerable.rb b/lib/java_buildpack/util/file_enumerable.rb index 0e76c74b13..8f1381717d 100644 --- a/lib/java_buildpack/util/file_enumerable.rb +++ b/lib/java_buildpack/util/file_enumerable.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/filtering_pathname.rb b/lib/java_buildpack/util/filtering_pathname.rb index 4ca55866c9..a136c98831 100644 --- a/lib/java_buildpack/util/filtering_pathname.rb +++ b/lib/java_buildpack/util/filtering_pathname.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -148,8 +147,8 @@ def glob(flags = 0) private - MUTATORS = [:chmod, :chown, :delete, :lchmod, :lchown, :make_link, :make_symlink, :mkdir, :mkpath, :rename, - :rmdir, :rmtree, :taint, :unlink, :untaint].to_set.freeze + MUTATORS = %i[chmod chown delete lchmod lchown make_link make_symlink mkdir mkpath rename rmdir rmtree taint + unlink untaint].to_set.freeze private_constant :MUTATORS diff --git a/lib/java_buildpack/util/find_single_directory.rb b/lib/java_buildpack/util/find_single_directory.rb index d1c4050650..be39a4a0b1 100644 --- a/lib/java_buildpack/util/find_single_directory.rb +++ b/lib/java_buildpack/util/find_single_directory.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/format_duration.rb b/lib/java_buildpack/util/format_duration.rb index 650a79cf05..9f9757d6ce 100644 --- a/lib/java_buildpack/util/format_duration.rb +++ b/lib/java_buildpack/util/format_duration.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/groovy_utils.rb b/lib/java_buildpack/util/groovy_utils.rb index c7aa0e3509..8095fc4dae 100644 --- a/lib/java_buildpack/util/groovy_utils.rb +++ b/lib/java_buildpack/util/groovy_utils.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/jar_finder.rb b/lib/java_buildpack/util/jar_finder.rb index 639d16292f..47ba294471 100644 --- a/lib/java_buildpack/util/jar_finder.rb +++ b/lib/java_buildpack/util/jar_finder.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/java_main_utils.rb b/lib/java_buildpack/util/java_main_utils.rb index 2a1ff2f4d7..b83e8e885c 100644 --- a/lib/java_buildpack/util/java_main_utils.rb +++ b/lib/java_buildpack/util/java_main_utils.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play.rb b/lib/java_buildpack/util/play.rb index 222f693f67..c0aed22ee0 100644 --- a/lib/java_buildpack/util/play.rb +++ b/lib/java_buildpack/util/play.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/base.rb b/lib/java_buildpack/util/play/base.rb index 6993b2098a..8891e4311a 100644 --- a/lib/java_buildpack/util/play/base.rb +++ b/lib/java_buildpack/util/play/base.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/factory.rb b/lib/java_buildpack/util/play/factory.rb index a529b19fa3..8dc786c7ec 100644 --- a/lib/java_buildpack/util/play/factory.rb +++ b/lib/java_buildpack/util/play/factory.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/post22.rb b/lib/java_buildpack/util/play/post22.rb index f79273440a..723e2e0c76 100644 --- a/lib/java_buildpack/util/play/post22.rb +++ b/lib/java_buildpack/util/play/post22.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/post22_dist.rb b/lib/java_buildpack/util/play/post22_dist.rb index 8e6d5374c6..0c94ff8e8c 100644 --- a/lib/java_buildpack/util/play/post22_dist.rb +++ b/lib/java_buildpack/util/play/post22_dist.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/post22_staged.rb b/lib/java_buildpack/util/play/post22_staged.rb index e5607241ec..26089228fe 100644 --- a/lib/java_buildpack/util/play/post22_staged.rb +++ b/lib/java_buildpack/util/play/post22_staged.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/pre22.rb b/lib/java_buildpack/util/play/pre22.rb index a17441257e..56f7d01a36 100644 --- a/lib/java_buildpack/util/play/pre22.rb +++ b/lib/java_buildpack/util/play/pre22.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/pre22_dist.rb b/lib/java_buildpack/util/play/pre22_dist.rb index 5faa782416..0e74712629 100644 --- a/lib/java_buildpack/util/play/pre22_dist.rb +++ b/lib/java_buildpack/util/play/pre22_dist.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/pre22_staged.rb b/lib/java_buildpack/util/play/pre22_staged.rb index d2afa49183..0668d01ea8 100644 --- a/lib/java_buildpack/util/play/pre22_staged.rb +++ b/lib/java_buildpack/util/play/pre22_staged.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/properties.rb b/lib/java_buildpack/util/properties.rb index 001723e189..972945c300 100644 --- a/lib/java_buildpack/util/properties.rb +++ b/lib/java_buildpack/util/properties.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/qualify_path.rb b/lib/java_buildpack/util/qualify_path.rb index bec68ccbc7..e54b49b802 100644 --- a/lib/java_buildpack/util/qualify_path.rb +++ b/lib/java_buildpack/util/qualify_path.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/ratpack_utils.rb b/lib/java_buildpack/util/ratpack_utils.rb index 69381b7a8d..594a33595e 100644 --- a/lib/java_buildpack/util/ratpack_utils.rb +++ b/lib/java_buildpack/util/ratpack_utils.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index b12fa48bd9..932986d7cd 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/shell.rb b/lib/java_buildpack/util/shell.rb index 470f1f3d51..326f5c8fc3 100644 --- a/lib/java_buildpack/util/shell.rb +++ b/lib/java_buildpack/util/shell.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/snake_case.rb b/lib/java_buildpack/util/snake_case.rb index 7aa60a7b91..008a8e1df8 100644 --- a/lib/java_buildpack/util/snake_case.rb +++ b/lib/java_buildpack/util/snake_case.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/space_case.rb b/lib/java_buildpack/util/space_case.rb index bfb65e0bfd..85d204f56c 100644 --- a/lib/java_buildpack/util/space_case.rb +++ b/lib/java_buildpack/util/space_case.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/spring_boot_utils.rb b/lib/java_buildpack/util/spring_boot_utils.rb index 528ef05c12..b668a9aad2 100644 --- a/lib/java_buildpack/util/spring_boot_utils.rb +++ b/lib/java_buildpack/util/spring_boot_utils.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/start_script.rb b/lib/java_buildpack/util/start_script.rb index f58b52c0b2..b1f22da79f 100644 --- a/lib/java_buildpack/util/start_script.rb +++ b/lib/java_buildpack/util/start_script.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/to_b.rb b/lib/java_buildpack/util/to_b.rb index c9f6512efd..1b54c33a59 100644 --- a/lib/java_buildpack/util/to_b.rb +++ b/lib/java_buildpack/util/to_b.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index 109c9f158b..bd6483f320 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 3d8dc8bd97..312cd36dd0 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/rakelib/package.rb b/rakelib/package.rb index c52a7dbf55..c0f4d27dc2 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -26,13 +25,13 @@ def self.version BUILDPACK_VERSION.version || 'unknown' end - ARCHITECTURES = %w(x86_64).freeze + ARCHITECTURES = %w[x86_64].freeze BUILD_DIR = 'build'.freeze BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze - PLATFORMS = %w(mountainlion trusty).freeze + PLATFORMS = %w[mountainlion trusty].freeze STAGING_DIR = "#{BUILD_DIR}/staging".freeze diff --git a/rakelib/package_task.rb b/rakelib/package_task.rb index 353b7197ef..22907dc2c1 100644 --- a/rakelib/package_task.rb +++ b/rakelib/package_task.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/rakelib/stage_buildpack_task.rb b/rakelib/stage_buildpack_task.rb index ed130572e0..f01c5969f6 100644 --- a/rakelib/stage_buildpack_task.rb +++ b/rakelib/stage_buildpack_task.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/resources/open_jdk_jre/bin/killjava.sh b/resources/open_jdk_jre/bin/killjava.sh index 106730238f..c83fe389d1 100755 --- a/resources/open_jdk_jre/bin/killjava.sh +++ b/resources/open_jdk_jre/bin/killjava.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/resources/oracle_jre/bin/killjava.sh b/resources/oracle_jre/bin/killjava.sh index 106730238f..c83fe389d1 100755 --- a/resources/oracle_jre/bin/killjava.sh +++ b/resources/oracle_jre/bin/killjava.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/resources/zulu_jre/bin/killjava.sh b/resources/zulu_jre/bin/killjava.sh index 5a25454560..12facf5ecb 100755 --- a/resources/zulu_jre/bin/killjava.sh +++ b/resources/zulu_jre/bin/killjava.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright (c) 2013-2017 the original author or authors. # diff --git a/spec/application_helper.rb b/spec/application_helper.rb index 44c53c3b2a..df7f4aca51 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/bin/compile_spec.rb b/spec/bin/compile_spec.rb index 1be6c427a0..3e10209234 100644 --- a/spec/bin/compile_spec.rb +++ b/spec/bin/compile_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/bin/detect_spec.rb b/spec/bin/detect_spec.rb index b21f23afea..05ca3aaf40 100644 --- a/spec/bin/detect_spec.rb +++ b/spec/bin/detect_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/bin/release_spec.rb b/spec/bin/release_spec.rb index 38cea57f2c..2441956bbf 100644 --- a/spec/bin/release_spec.rb +++ b/spec/bin/release_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/component_helper.rb b/spec/component_helper.rb index 1bd2d4515d..0e7b76fb9f 100644 --- a/spec/component_helper.rb +++ b/spec/component_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/console_helper.rb b/spec/console_helper.rb index 0d674c3505..5c5c6b289c 100644 --- a/spec/console_helper.rb +++ b/spec/console_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index bf28bbfe5b..df38e9e923 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -43,19 +42,19 @@ let(:sandbox) { droplet.sandbox } let(:java_home) do - delegate = instance_double('MutableJavaHome', root: app_dir + '.test-java-home', version: %w(1 7 55 u60)) + delegate = instance_double('MutableJavaHome', root: app_dir + '.test-java-home', version: %w[1 7 55 u60]) JavaBuildpack::Component::ImmutableJavaHome.new delegate, app_dir end let(:environment_variables) do java_opts = JavaBuildpack::Component::EnvironmentVariables.new app_dir - java_opts.concat %w(test-var-2 test-var-1) + java_opts.concat %w[test-var-2 test-var-1] java_opts end let(:java_opts) do java_opts = JavaBuildpack::Component::JavaOpts.new app_dir - java_opts.concat %w(test-opt-2 test-opt-1) + java_opts.concat %w[test-opt-2 test-opt-1] java_opts end diff --git a/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb b/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb index a1a134493c..d4964d7e2e 100644 --- a/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb +++ b/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index d54723921b..56dc793a71 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -32,7 +31,7 @@ end before do |example| - %w(bin config lib resources).each { |dir| FileUtils.cp_r dir, buildpack_dir } + %w[bin config lib resources].each { |dir| FileUtils.cp_r dir, buildpack_dir } buildpack_fixture = example.metadata[:buildpack_fixture] FileUtils.cp_r "spec/fixtures/#{buildpack_fixture.chomp}/.", buildpack_dir if buildpack_fixture diff --git a/spec/internet_availability_helper.rb b/spec/internet_availability_helper.rb index ffc9ec5f89..a033165b29 100644 --- a/spec/internet_availability_helper.rb +++ b/spec/internet_availability_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/buildpack_spec.rb b/spec/java_buildpack/buildpack_spec.rb index 8c9e0b6e49..0c6deb0661 100644 --- a/spec/java_buildpack/buildpack_spec.rb +++ b/spec/java_buildpack/buildpack_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/buildpack_version_spec.rb b/spec/java_buildpack/buildpack_version_spec.rb index dde6924168..d917f177a3 100644 --- a/spec/java_buildpack/buildpack_version_spec.rb +++ b/spec/java_buildpack/buildpack_version_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/additional_libraries_spec.rb b/spec/java_buildpack/component/additional_libraries_spec.rb index 8c68b06751..36df0ffbda 100644 --- a/spec/java_buildpack/component/additional_libraries_spec.rb +++ b/spec/java_buildpack/component/additional_libraries_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/application_spec.rb b/spec/java_buildpack/component/application_spec.rb index 0469a724a3..6978414c87 100644 --- a/spec/java_buildpack/component/application_spec.rb +++ b/spec/java_buildpack/component/application_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/base_component_spec.rb b/spec/java_buildpack/component/base_component_spec.rb index 883fb91374..bebb65a858 100644 --- a/spec/java_buildpack/component/base_component_spec.rb +++ b/spec/java_buildpack/component/base_component_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/droplet_spec.rb b/spec/java_buildpack/component/droplet_spec.rb index c779e4b8e8..d2e5171a6a 100644 --- a/spec/java_buildpack/component/droplet_spec.rb +++ b/spec/java_buildpack/component/droplet_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/environment_variables_spec.rb b/spec/java_buildpack/component/environment_variables_spec.rb index 04f0ca2e90..7a8affd1bf 100644 --- a/spec/java_buildpack/component/environment_variables_spec.rb +++ b/spec/java_buildpack/component/environment_variables_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index 160c4cb4c5..048cc0f0bc 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -39,7 +38,7 @@ end it 'returns the delegate version' do - expect(immutable_java_home.version).to eq(%w(1 2 3 u04)) + expect(immutable_java_home.version).to eq(%w[1 2 3 u04]) end it 'returns the delegate Java 8 or later' do diff --git a/spec/java_buildpack/component/java_opts_spec.rb b/spec/java_buildpack/component/java_opts_spec.rb index 280d9f934d..674aee2f61 100644 --- a/spec/java_buildpack/component/java_opts_spec.rb +++ b/spec/java_buildpack/component/java_opts_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/modular_component_spec.rb b/spec/java_buildpack/component/modular_component_spec.rb index 2aa17d7af3..bcb1a16e91 100644 --- a/spec/java_buildpack/component/modular_component_spec.rb +++ b/spec/java_buildpack/component/modular_component_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/mutable_java_home_spec.rb b/spec/java_buildpack/component/mutable_java_home_spec.rb index 8c0a4d30d5..7b3d89ac40 100644 --- a/spec/java_buildpack/component/mutable_java_home_spec.rb +++ b/spec/java_buildpack/component/mutable_java_home_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/services_spec.rb b/spec/java_buildpack/component/services_spec.rb index 75c377817c..7bf7926c3c 100644 --- a/spec/java_buildpack/component/services_spec.rb +++ b/spec/java_buildpack/component/services_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -59,18 +58,18 @@ end it 'returns true from one_service? if there is a matching service with one required group credentials' do - expect(services.one_service?('test-tag', %w(uri other))).to be - expect(services.one_service?(/test-tag/, %w(uri other))).to be + expect(services.one_service?('test-tag', %w[uri other])).to be + expect(services.one_service?(/test-tag/, %w[uri other])).to be end it 'returns true from one_service? if there is a matching service with two required group credentials' do - expect(services.one_service?('test-tag', %w(h1 h2))).to be - expect(services.one_service?(/test-tag/, %w(h1 h2))).to be + expect(services.one_service?('test-tag', %w[h1 h2])).to be + expect(services.one_service?(/test-tag/, %w[h1 h2])).to be end it 'returns false from one_service? if there is a matching service with no required group credentials' do - expect(services.one_service?('test-tag', %w(foo bar))).not_to be - expect(services.one_service?(/test-tag/, %w(foo bar))).not_to be + expect(services.one_service?('test-tag', %w[foo bar])).not_to be + expect(services.one_service?(/test-tag/, %w[foo bar])).not_to be end it 'returns nil from find_service? if there is no service that matches' do diff --git a/spec/java_buildpack/component/versioned_dependency_component_spec.rb b/spec/java_buildpack/component/versioned_dependency_component_spec.rb index 699d386dc5..6eba9d6f04 100644 --- a/spec/java_buildpack/component/versioned_dependency_component_spec.rb +++ b/spec/java_buildpack/component/versioned_dependency_component_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/dist_zip_like_spec.rb b/spec/java_buildpack/container/dist_zip_like_spec.rb index 5eb93f4b98..3d2a1657f3 100644 --- a/spec/java_buildpack/container/dist_zip_like_spec.rb +++ b/spec/java_buildpack/container/dist_zip_like_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/dist_zip_spec.rb b/spec/java_buildpack/container/dist_zip_spec.rb index 3f706b8893..7feba8d203 100644 --- a/spec/java_buildpack/container/dist_zip_spec.rb +++ b/spec/java_buildpack/container/dist_zip_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/groovy_spec.rb b/spec/java_buildpack/container/groovy_spec.rb index 27e4b725dc..e1f45ae2bc 100644 --- a/spec/java_buildpack/container/groovy_spec.rb +++ b/spec/java_buildpack/container/groovy_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index 1c22c8aa43..383a271a12 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/play_framework_spec.rb b/spec/java_buildpack/container/play_framework_spec.rb index fa3e18d199..b65f1f91a8 100644 --- a/spec/java_buildpack/container/play_framework_spec.rb +++ b/spec/java_buildpack/container/play_framework_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/ratpack_spec.rb b/spec/java_buildpack/container/ratpack_spec.rb index 5b1b1b5d4c..67d12527c7 100644 --- a/spec/java_buildpack/container/ratpack_spec.rb +++ b/spec/java_buildpack/container/ratpack_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/spring_boot_cli_spec.rb b/spec/java_buildpack/container/spring_boot_cli_spec.rb index c4a375b66d..f31eed64e4 100644 --- a/spec/java_buildpack/container/spring_boot_cli_spec.rb +++ b/spec/java_buildpack/container/spring_boot_cli_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/spring_boot_spec.rb b/spec/java_buildpack/container/spring_boot_spec.rb index 125a01dff1..018253d7f0 100644 --- a/spec/java_buildpack/container/spring_boot_spec.rb +++ b/spec/java_buildpack/container/spring_boot_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb index ee67999706..348327d2d3 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb index b84317c440..ac747917b1 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb index 5aa2f5da04..f2d00a960e 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb index e7e2869e7d..c41b36c0b1 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb index 8384631c24..c080303da2 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb index b65808f62c..9adc96b27c 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb index 5deef0db62..aaf2704c08 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -36,7 +35,7 @@ context do before do - allow(services).to receive(:one_service?).with(/session-replication/, %w(hostname host), 'port', 'password') + allow(services).to receive(:one_service?).with(/session-replication/, %w[hostname host], 'port', 'password') .and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'hostname' => 'test-host', 'port' => 'test-port', @@ -71,7 +70,7 @@ context do before do - allow(services).to receive(:one_service?).with(/session-replication/, %w(hostname host), 'port', 'password') + allow(services).to receive(:one_service?).with(/session-replication/, %w[hostname host], 'port', 'password') .and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'host' => 'test-host', 'port' => 'test-port', diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index 8b804b848b..ee65087d6c 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index faac6f8dcb..1cc192e5f6 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb b/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb index c684ef2c5e..c1732d04a5 100644 --- a/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb +++ b/spec/java_buildpack/framework/container_certificate_trust_store_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/container_customizer_spec.rb b/spec/java_buildpack/framework/container_customizer_spec.rb index 04654f06ba..37f53879a1 100644 --- a/spec/java_buildpack/framework/container_customizer_spec.rb +++ b/spec/java_buildpack/framework/container_customizer_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/debug_spec.rb b/spec/java_buildpack/framework/debug_spec.rb index f3f6653e5b..fd361165fe 100644 --- a/spec/java_buildpack/framework/debug_spec.rb +++ b/spec/java_buildpack/framework/debug_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb index 10f305a021..fc2d8a165c 100644 --- a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb +++ b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb index 9409c163a6..f3475fa342 100644 --- a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index c906487f9a..187e14a1c7 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -29,8 +28,8 @@ context do before do - allow(services).to receive(:one_service?).with(/ruxit|dynatrace/, %w(environmentid tenant), - %w(apitoken tenanttoken)).and_return(true) + allow(services).to receive(:one_service?).with(/ruxit|dynatrace/, %w[environmentid tenant], + %w[apitoken tenanttoken]).and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'apitoken' => 'test-apitoken', 'tenant' => 'test-tenant', 'server' => 'test-server' }) diff --git a/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb b/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb index 94c4810824..d7b719b58d 100644 --- a/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb +++ b/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index 3347a55583..958355f63e 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -27,7 +26,7 @@ let(:vcap_application) do { 'application_name' => 'test-application-name', - 'application_uris' => %w(test-application-uri-0 test-application-uri-1) } + 'application_uris' => %w[test-application-uri-0 test-application-uri-1] } end it 'does not detect without introscope-n/a service' do diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index 42f179ff6e..2a018052b5 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/jmx_spec.rb b/spec/java_buildpack/framework/jmx_spec.rb index 6b7e270733..aec788dd68 100644 --- a/spec/java_buildpack/framework/jmx_spec.rb +++ b/spec/java_buildpack/framework/jmx_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb index 9d043d755c..db4fc51c97 100644 --- a/spec/java_buildpack/framework/jrebel_agent_spec.rb +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index 4d59eed273..9149308a2e 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -48,10 +47,10 @@ 'groups' => [ { 'label' => 'test-group-1', - 'members' => %w(test-group-1-member-1 test-group-1-member-2) + 'members' => %w[test-group-1-member-1 test-group-1-member-2] }, { 'label' => 'test-group-2', - 'members' => %w(test-group-2-member-1 test-group-2-member-2) + 'members' => %w[test-group-2-member-1 test-group-2-member-2] } ] } diff --git a/spec/java_buildpack/framework/maria_db_jdbc_spec.rb b/spec/java_buildpack/framework/maria_db_jdbc_spec.rb index 9d43cc7f72..c92cdbe371 100644 --- a/spec/java_buildpack/framework/maria_db_jdbc_spec.rb +++ b/spec/java_buildpack/framework/maria_db_jdbc_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/new_relic_agent_spec.rb b/spec/java_buildpack/framework/new_relic_agent_spec.rb index 5a00aa7b37..2f9c719f93 100644 --- a/spec/java_buildpack/framework/new_relic_agent_spec.rb +++ b/spec/java_buildpack/framework/new_relic_agent_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -29,7 +28,7 @@ context do before do - allow(services).to receive(:one_service?).with(/newrelic/, %w(licenseKey license_key)).and_return(true) + allow(services).to receive(:one_service?).with(/newrelic/, %w[licenseKey license_key]).and_return(true) end it 'detects with newrelic-n/a service' do diff --git a/spec/java_buildpack/framework/play_framework_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/play_framework_auto_reconfiguration_spec.rb index 2ee6b1b7fa..df665e6959 100644 --- a/spec/java_buildpack/framework/play_framework_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/play_framework_auto_reconfiguration_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/play_framework_jpa_plugin_spec.rb b/spec/java_buildpack/framework/play_framework_jpa_plugin_spec.rb index 8e85780d85..45e16d41e2 100644 --- a/spec/java_buildpack/framework/play_framework_jpa_plugin_spec.rb +++ b/spec/java_buildpack/framework/play_framework_jpa_plugin_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/postgresql_jdbc_spec.rb b/spec/java_buildpack/framework/postgresql_jdbc_spec.rb index f3c91b2b56..706bd6105a 100644 --- a/spec/java_buildpack/framework/postgresql_jdbc_spec.rb +++ b/spec/java_buildpack/framework/postgresql_jdbc_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb index aa0bb2a7b6..1f534d49f6 100644 --- a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb +++ b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2016 the original author or authors. # diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb index 1644ebfb4d..215aec9fd1 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index 2a5df82fc3..1ea894f112 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/spring_insight_spec.rb b/spec/java_buildpack/framework/spring_insight_spec.rb index 513ab09e33..678867652f 100644 --- a/spec/java_buildpack/framework/spring_insight_spec.rb +++ b/spec/java_buildpack/framework/spring_insight_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/your_kit_profiler_spec.rb b/spec/java_buildpack/framework/your_kit_profiler_spec.rb index 1724bc8616..55c63d5382 100644 --- a/spec/java_buildpack/framework/your_kit_profiler_spec.rb +++ b/spec/java_buildpack/framework/your_kit_profiler_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index 6c4252174b..de35084acf 100644 --- a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index a0a8a77b11..934e3c58cb 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index 66f5297218..1b054d39f1 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/logging/delegating_logger_spec.rb b/spec/java_buildpack/logging/delegating_logger_spec.rb index 0ad4d47799..73488f228c 100644 --- a/spec/java_buildpack/logging/delegating_logger_spec.rb +++ b/spec/java_buildpack/logging/delegating_logger_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/logging/logger_factory_spec.rb b/spec/java_buildpack/logging/logger_factory_spec.rb index 825b7b75e1..6bede3ee72 100644 --- a/spec/java_buildpack/logging/logger_factory_spec.rb +++ b/spec/java_buildpack/logging/logger_factory_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/repository/configured_item_spec.rb b/spec/java_buildpack/repository/configured_item_spec.rb index 89399c20d5..3e15952798 100644 --- a/spec/java_buildpack/repository/configured_item_spec.rb +++ b/spec/java_buildpack/repository/configured_item_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/repository/repository_index_spec.rb b/spec/java_buildpack/repository/repository_index_spec.rb index ba7da86386..799b599b79 100644 --- a/spec/java_buildpack/repository/repository_index_spec.rb +++ b/spec/java_buildpack/repository/repository_index_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -37,23 +36,23 @@ it 'loads index' do allow(application_cache).to receive(:get).with(%r{/test-uri/index\.yml}) .and_yield(Pathname.new('spec/fixtures/test-index.yml').open) - allow(JavaBuildpack::Repository::VersionResolver).to receive(:resolve).with('test-version', %w(resolved-version)) + allow(JavaBuildpack::Repository::VersionResolver).to receive(:resolve).with('test-version', %w[resolved-version]) .and_return('resolved-version') repository_index = described_class.new('{platform}/{architecture}/test-uri') - expect(repository_index.find_item('test-version')).to eq(%w(resolved-version resolved-uri)) + expect(repository_index.find_item('test-version')).to eq(%w[resolved-version resolved-uri]) end it 'copes with trailing slash in repository URI' do allow(application_cache).to receive(:get).with(%r{/test-uri/index\.yml}) .and_yield(Pathname.new('spec/fixtures/test-index.yml').open) - allow(JavaBuildpack::Repository::VersionResolver).to receive(:resolve).with('test-version', %w(resolved-version)) + allow(JavaBuildpack::Repository::VersionResolver).to receive(:resolve).with('test-version', %w[resolved-version]) .and_return('resolved-version') repository_index = described_class.new('{platform}/{architecture}/test-uri/') - expect(repository_index.find_item('test-version')).to eq(%w(resolved-version resolved-uri)) + expect(repository_index.find_item('test-version')).to eq(%w[resolved-version resolved-uri]) end it 'substitutes the default repository root' do diff --git a/spec/java_buildpack/repository/version_resolver_spec.rb b/spec/java_buildpack/repository/version_resolver_spec.rb index fc331f8ca7..afd62bf17a 100644 --- a/spec/java_buildpack/repository/version_resolver_spec.rb +++ b/spec/java_buildpack/repository/version_resolver_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -23,7 +22,7 @@ include_context 'logging_helper' let(:versions) do - %w(1.6.0_26 1.6.0_27 1.6.0_112 1.6.0_102 1.6.0_45RELEASE 1.6.1_14 1.7.0_19 1.7.0_21 1.8.0_M-7 1.8.0_05 2.0.0 2.0.0a) + %w[1.6.0_26 1.6.0_27 1.6.0_112 1.6.0_102 1.6.0_45RELEASE 1.6.1_14 1.7.0_19 1.7.0_21 1.8.0_M-7 1.8.0_05 2.0.0 2.0.0a] end it 'resolves the default version if no candidate is supplied' do diff --git a/spec/java_buildpack/util/cache/application_cache_spec.rb b/spec/java_buildpack/util/cache/application_cache_spec.rb index 74cc0b0918..b8815a4432 100644 --- a/spec/java_buildpack/util/cache/application_cache_spec.rb +++ b/spec/java_buildpack/util/cache/application_cache_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/cache/cached_file_spec.rb b/spec/java_buildpack/util/cache/cached_file_spec.rb index 18b7315928..e2dfd25f5e 100644 --- a/spec/java_buildpack/util/cache/cached_file_spec.rb +++ b/spec/java_buildpack/util/cache/cached_file_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -27,7 +26,7 @@ let(:file_cache) { described_class.new(app_dir, 'http://foo-uri/', true) } it 'does not create any files on initialization' do - %w(cached etag last_modified).each { |extension| expect(cache_file(extension)).not_to exist } + %w[cached etag last_modified].each { |extension| expect(cache_file(extension)).not_to exist } end it 'creates cache_root if mutable' do @@ -77,13 +76,13 @@ it 'destroys all files' do file_cache.destroy - %w(cached etag last_modified).each { |extension| expect(cache_file(extension)).not_to exist } + %w[cached etag last_modified].each { |extension| expect(cache_file(extension)).not_to exist } end it 'does not destroy all files if immutable' do described_class.new(app_dir, 'http://foo-uri/', false).destroy - %w(cached etag last_modified).each { |extension| expect(cache_file(extension)).to exist } + %w[cached etag last_modified].each { |extension| expect(cache_file(extension)).to exist } end it 'calls the block with the content of the etag file' do diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 0d3b9e0479..b418898974 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/cache/internet_availability_spec.rb b/spec/java_buildpack/util/cache/internet_availability_spec.rb index 610ee3ce63..a1d39af14b 100644 --- a/spec/java_buildpack/util/cache/internet_availability_spec.rb +++ b/spec/java_buildpack/util/cache/internet_availability_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/cache/yield_file_with_content.rb b/spec/java_buildpack/util/cache/yield_file_with_content.rb index 530e79927d..49d29b9911 100644 --- a/spec/java_buildpack/util/cache/yield_file_with_content.rb +++ b/spec/java_buildpack/util/cache/yield_file_with_content.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 363664ca11..d81790049a 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/constantize_spec.rb b/spec/java_buildpack/util/constantize_spec.rb index f8ae33d2cf..9d11559e02 100644 --- a/spec/java_buildpack/util/constantize_spec.rb +++ b/spec/java_buildpack/util/constantize_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index a7fb7b66b6..10c8d622e8 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/format_duration_spec.rb b/spec/java_buildpack/util/format_duration_spec.rb index efde5470f8..a1a526ab5c 100644 --- a/spec/java_buildpack/util/format_duration_spec.rb +++ b/spec/java_buildpack/util/format_duration_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/java_main_utils_spec.rb b/spec/java_buildpack/util/java_main_utils_spec.rb index 26af2eb7d6..08c8891c1e 100644 --- a/spec/java_buildpack/util/java_main_utils_spec.rb +++ b/spec/java_buildpack/util/java_main_utils_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/base_spec.rb b/spec/java_buildpack/util/play/base_spec.rb index 29a173a51f..04ce456749 100644 --- a/spec/java_buildpack/util/play/base_spec.rb +++ b/spec/java_buildpack/util/play/base_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/factory_spec.rb b/spec/java_buildpack/util/play/factory_spec.rb index 7ab1d2787e..db9c537fd0 100644 --- a/spec/java_buildpack/util/play/factory_spec.rb +++ b/spec/java_buildpack/util/play/factory_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/post22_dist_spec.rb b/spec/java_buildpack/util/play/post22_dist_spec.rb index 33772ca3ce..153ff08849 100644 --- a/spec/java_buildpack/util/play/post22_dist_spec.rb +++ b/spec/java_buildpack/util/play/post22_dist_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index eb12924ba6..dd4bba51f3 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/post22_staged_spec.rb b/spec/java_buildpack/util/play/post22_staged_spec.rb index 4fe13d0778..6746b2e2ca 100644 --- a/spec/java_buildpack/util/play/post22_staged_spec.rb +++ b/spec/java_buildpack/util/play/post22_staged_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index 1c8a8c1936..8c59eb744e 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/pre22_spec.rb b/spec/java_buildpack/util/play/pre22_spec.rb index 4e6f41989d..12fe045d83 100644 --- a/spec/java_buildpack/util/play/pre22_spec.rb +++ b/spec/java_buildpack/util/play/pre22_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index 7d24e5bd7d..743a9b52da 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/properties_spec.rb b/spec/java_buildpack/util/properties_spec.rb index 644c7f1fca..a9fcb8e118 100644 --- a/spec/java_buildpack/util/properties_spec.rb +++ b/spec/java_buildpack/util/properties_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/ratpack_utils_spec.rb b/spec/java_buildpack/util/ratpack_utils_spec.rb index 7feddf330c..1c7304d74d 100644 --- a/spec/java_buildpack/util/ratpack_utils_spec.rb +++ b/spec/java_buildpack/util/ratpack_utils_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/sanitize_spec.rb b/spec/java_buildpack/util/sanitize_spec.rb index 7f00251cc8..1afec26699 100644 --- a/spec/java_buildpack/util/sanitize_spec.rb +++ b/spec/java_buildpack/util/sanitize_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/shell_spec.rb b/spec/java_buildpack/util/shell_spec.rb index 71d0b8ddc0..f34b6067c4 100644 --- a/spec/java_buildpack/util/shell_spec.rb +++ b/spec/java_buildpack/util/shell_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/spring_boot_utils_spec.rb b/spec/java_buildpack/util/spring_boot_utils_spec.rb index be62514baa..8911cfc33b 100644 --- a/spec/java_buildpack/util/spring_boot_utils_spec.rb +++ b/spec/java_buildpack/util/spring_boot_utils_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/tokenized_version_spec.rb b/spec/java_buildpack/util/tokenized_version_spec.rb index 9b9b943c96..1e5f3fac21 100644 --- a/spec/java_buildpack/util/tokenized_version_spec.rb +++ b/spec/java_buildpack/util/tokenized_version_spec.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/logging_helper.rb b/spec/logging_helper.rb index 6c8e09560a..cde1815ff1 100644 --- a/spec/logging_helper.rb +++ b/spec/logging_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/memory_limit_helper.rb b/spec/memory_limit_helper.rb index f42f6242fd..687537b083 100644 --- a/spec/memory_limit_helper.rb +++ b/spec/memory_limit_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index bb3b4d5a99..dca5ec4181 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,3 @@ -# Encoding: utf-8 # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # From dbb8ec3e7c815726828e1a129a472a3cd27d2c28 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 2 May 2017 06:49:38 -0700 Subject: [PATCH 264/812] Remove Darwin Binaries from Offline Buildpack Previously, Darwin binaries were included in the builds of offline buildpacks. While it's important for development and testing that these binaries exist, they do not need to be packaged into the offline buildpack that is distributed for Cloud Foundry. This change removes them, saving some space in the offline buildpack. --- rakelib/package.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/package.rb b/rakelib/package.rb index c0f4d27dc2..4a611f7fbd 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -31,7 +31,7 @@ def self.version BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze - PLATFORMS = %w[mountainlion trusty].freeze + PLATFORMS = %w[trusty].freeze STAGING_DIR = "#{BUILD_DIR}/staging".freeze From da9329655ce25c2b50b8e5949a8b8b887bc13ee4 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 2 May 2017 09:21:32 -0700 Subject: [PATCH 265/812] Remove Most UTF-8 Characters Previously, there were a handful of UTF-8 characters (and one specifically in an error message) in the repository. This caused issues when the removal of explicit Ruby encodings happened as some other parties were still testing against Ruby 1.9. This change removes most of the UTF-8 characters in the repository, leaving a single test that is specifically looking at special UTF-8 characters. --- CONTRIBUTING.md | 2 +- docs/buildpack-modes.md | 2 +- lib/java_buildpack/buildpack.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 404fccfb95..f352b769b5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -_Have something you’d like to contribute to the buildpack? We welcome pull requests, but ask that you carefully read this document first to understand how best to submit them; what kind of changes are likely to be accepted; and what to expect from the Cloud Foundry Java Experience team when evaluating your submission._ +_Have something you'd like to contribute to the buildpack? We welcome pull requests, but ask that you carefully read this document first to understand how best to submit them; what kind of changes are likely to be accepted; and what to expect from the Cloud Foundry Java Experience team when evaluating your submission._ _Please refer back to this document as a checklist before issuing any pull request; this will save time for everyone!_ diff --git a/docs/buildpack-modes.md b/docs/buildpack-modes.md index c74621dc40..1035504702 100644 --- a/docs/buildpack-modes.md +++ b/docs/buildpack-modes.md @@ -2,7 +2,7 @@ The Java Buildpack has three execution modes as described in the blog post, ['Packaged and Offline Buildpacks'][l]. * **Easy Mode:** Uses the repository at `https://java-buildpack.cloudfoundry.org`. This does not require any cloning or downloading unless you want to modify the Cloud Foundry provided buildpack. This is the default, and what we recommend to anyone who asks. -* **Expert Mode:** Refers to a repository hosted at a different location, possibly on an internal network. The [structure of the repository][r] is defined as an HTTP-accessible collection of files. The repository root must contain an `index.yml` file that is a mapping of concrete versions to absolute URIs. This repository can be created manually or [creating a replica](#replicating-the-repository-optional) for the repository at `https://java-buildpack.cloudfoundry.org`. This is what we would recommend to any customer that didn’t want to access the Internet. It’s easy to keep applications secure and up-to-date, but requires the expertise to run a web-server and keep it up to date. +* **Expert Mode:** Refers to a repository hosted at a different location, possibly on an internal network. The [structure of the repository][r] is defined as an HTTP-accessible collection of files. The repository root must contain an `index.yml` file that is a mapping of concrete versions to absolute URIs. This repository can be created manually or [creating a replica](#replicating-the-repository-optional) for the repository at `https://java-buildpack.cloudfoundry.org`. This is what we would recommend to any customer that didn't want to access the Internet. It's easy to keep applications secure and up-to-date, but requires the expertise to run a web-server and keep it up to date. * **Offline Mode:** Uses only the packaged internal cache. This is what we recommend if you wanted a single, self-contained artifact. The downside is having to package and keep all your dependencies up to date. diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 4373d14dd6..57a1b57c63 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -188,7 +188,7 @@ def names(components) end def no_container - raise 'No container can run this application. Please ensure that you’ve pushed a valid JVM artifact or ' \ + raise 'No container can run this application. Please ensure that you\'ve pushed a valid JVM artifact or ' \ 'artifacts using the -p command line argument or path manifest entry. Information about valid JVM ' \ 'artifacts can be found at https://github.com/cloudfoundry/java-buildpack#additional-documentation. ' end From 5cce8e1f1c84ab3d8df572a46a49b158e8c11cd7 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 May 2017 13:34:22 -0700 Subject: [PATCH 266/812] Version Tasks This change adds version tasks that output the resolved versions of all dependencies in human-readable, JSON, and YAML format. --- .idea/.rakeTasks | 2 +- .idea/runConfigurations/versions.xml | 25 +++ .idea/runConfigurations/versions__JSON_.xml | 25 +++ .idea/runConfigurations/versions__YAML_.xml | 25 +++ Gemfile | 1 + Gemfile.lock | 3 + Rakefile | 2 + ci/versions-json.sh | 28 +++ ci/versions-json.yml | 27 +++ ci/versions-yaml.sh | 28 +++ ci/versions-yaml.yml | 27 +++ ci/versions.sh | 28 +++ ci/versions.yml | 27 +++ java-buildpack.iml | 1 + rakelib/versions_task.rb | 235 ++++++++++++++++++++ 15 files changed, 483 insertions(+), 1 deletion(-) create mode 100644 .idea/runConfigurations/versions.xml create mode 100644 .idea/runConfigurations/versions__JSON_.xml create mode 100644 .idea/runConfigurations/versions__YAML_.xml create mode 100755 ci/versions-json.sh create mode 100644 ci/versions-json.yml create mode 100755 ci/versions-yaml.sh create mode 100644 ci/versions-yaml.yml create mode 100755 ci/versions.sh create mode 100644 ci/versions.yml create mode 100644 rakelib/versions_task.rb diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index 56aac576a4..7f4e6da3bd 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/.idea/runConfigurations/versions.xml b/.idea/runConfigurations/versions.xml new file mode 100644 index 0000000000..36aac7eca9 --- /dev/null +++ b/.idea/runConfigurations/versions.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/versions__JSON_.xml b/.idea/runConfigurations/versions__JSON_.xml new file mode 100644 index 0000000000..1d3402880a --- /dev/null +++ b/.idea/runConfigurations/versions__JSON_.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/versions__YAML_.xml b/.idea/runConfigurations/versions__YAML_.xml new file mode 100644 index 0000000000..1acd036c8b --- /dev/null +++ b/.idea/runConfigurations/versions__YAML_.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gemfile b/Gemfile index a5930cc0a2..d8344bf29d 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,7 @@ group :development do gem 'rubocop-rspec' gem 'rubyzip' gem 'tee' + gem 'terminal-table' gem 'webmock' gem 'yard' end diff --git a/Gemfile.lock b/Gemfile.lock index 4260ce570b..1989ed5844 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,6 +41,8 @@ GEM rubyzip (1.2.1) safe_yaml (1.0.4) tee (1.0.0) + terminal-table (1.7.0) + unicode-display_width (~> 1.1) unicode-display_width (1.2.1) webmock (3.0.1) addressable (>= 2.3.6) @@ -59,6 +61,7 @@ DEPENDENCIES rubocop-rspec rubyzip tee + terminal-table webmock yard diff --git a/Rakefile b/Rakefile index cfce5f0dcc..b87362c3cf 100644 --- a/Rakefile +++ b/Rakefile @@ -36,9 +36,11 @@ $LOAD_PATH.unshift File.expand_path('..', __FILE__) require 'rakelib/dependency_cache_task' require 'rakelib/stage_buildpack_task' require 'rakelib/package_task' +require 'rakelib/versions_task' Package::DependencyCacheTask.new Package::StageBuildpackTask.new(Dir['bin/**/*', 'config/**/*', 'lib/**/*', 'resources/**/*'] .reject { |f| File.directory? f }) Package::PackageTask.new +Package::VersionsTask.new task default: %w[rubocop check_api_doc spec] diff --git a/ci/versions-json.sh b/ci/versions-json.sh new file mode 100755 index 0000000000..fcb55ffdca --- /dev/null +++ b/ci/versions-json.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +export LANG=en_US.UTF-8 +export LANGUAGE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +eval "$(rbenv init -)" + +pushd java-buildpack + bundle install + bundle exec rake versions:json +popd diff --git a/ci/versions-json.yml b/ci/versions-json.yml new file mode 100644 index 0000000000..03273ec22d --- /dev/null +++ b/ci/versions-json.yml @@ -0,0 +1,27 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +platform: linux + +image_resource: + type: docker-image + source: + repository: cfje/java-buildpack + +inputs: +- name: java-buildpack + +run: + path: java-buildpack/ci/versions-json.sh diff --git a/ci/versions-yaml.sh b/ci/versions-yaml.sh new file mode 100755 index 0000000000..f8d0c51caf --- /dev/null +++ b/ci/versions-yaml.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +export LANG=en_US.UTF-8 +export LANGUAGE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +eval "$(rbenv init -)" + +pushd java-buildpack + bundle install + bundle exec rake versions:yaml +popd diff --git a/ci/versions-yaml.yml b/ci/versions-yaml.yml new file mode 100644 index 0000000000..d9dee887de --- /dev/null +++ b/ci/versions-yaml.yml @@ -0,0 +1,27 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +platform: linux + +image_resource: + type: docker-image + source: + repository: cfje/java-buildpack + +inputs: +- name: java-buildpack + +run: + path: java-buildpack/ci/versions-yaml.sh diff --git a/ci/versions.sh b/ci/versions.sh new file mode 100755 index 0000000000..c4decb0391 --- /dev/null +++ b/ci/versions.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +export LANG=en_US.UTF-8 +export LANGUAGE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +eval "$(rbenv init -)" + +pushd java-buildpack + bundle install + bundle exec rake versions +popd diff --git a/ci/versions.yml b/ci/versions.yml new file mode 100644 index 0000000000..2968dc4495 --- /dev/null +++ b/ci/versions.yml @@ -0,0 +1,27 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +platform: linux + +image_resource: + type: docker-image + source: + repository: cfje/java-buildpack + +inputs: +- name: java-buildpack + +run: + path: java-buildpack/ci/versions.sh diff --git a/java-buildpack.iml b/java-buildpack.iml index 857eeecdf5..90a0374579 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -290,6 +290,7 @@ + diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb new file mode 100644 index 0000000000..ad3f468ea5 --- /dev/null +++ b/rakelib/versions_task.rb @@ -0,0 +1,235 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) + +require 'java_buildpack/logging/logger_factory' +require 'java_buildpack/repository/version_resolver' +require 'java_buildpack/util/configuration_utils' +require 'java_buildpack/util/cache/download_cache' +require 'json' +require 'rake/tasklib' +require 'rakelib/package' +require 'terminal-table' +require 'yaml' + +module Package + + class VersionsTask < Rake::TaskLib + include Package + + def initialize + JavaBuildpack::Logging::LoggerFactory.instance.setup "#{BUILD_DIR}/" + + desc 'Display the versions of buildpack dependencies in human readable form' + task versions: [] do + v = versions + + puts Terminal::Table.new title: "Java Buildpack #{v['buildpack']}", + rows: v['dependencies'] + .sort_by { |dependency| dependency['name'] } + .map { |dependency| [dependency['name'], dependency['version']] } + end + + namespace 'versions' do + desc 'Display the versions of buildpack dependencies in JSON form' + task json: [] do + puts JSON.pretty_generate(versions) + end + + desc 'Display the versions of buildpack dependencies in YAML form' + task yaml: [] do + puts YAML.dump(versions) + end + end + end + + private + + ARCHITECTURE_PATTERN = /\{architecture\}/ + + DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/ + + NAME_MAPPINGS = { + 'access_logging_support' => 'Tomcat Access Logging Support', + 'app_dynamics_agent' => 'AppDynamics Agent', + 'container_certificate_trust_store' => 'Container Certificate Trust Store', + 'container_customizer' => 'Spring Boot Container Customizer', + 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', + 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', + 'dynatrace_one_agent' => 'Dynatrace OneAgent', + 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', + 'groovy' => 'Groovy', + 'jre' => 'OpenJDK JRE', + 'jrebel_agent' => 'JRebel Agent', + 'lifecycle_support' => 'Tomcat Lifecycle Support', + 'logging_support' => 'Tomcat Logging Support', + 'luna_security_provider' => 'Gemalto Luna Security Provider', + 'maria_db_jdbc' => 'MariaDB JDBC Driver', + 'memory_calculator' => 'Memory Calculator', + 'new_relic_agent' => 'New Relic Agent', + 'play_framework_auto_reconfiguration' => 'Play Framework Auto-reconfiguration', + 'play_framework_jpa_plugin' => 'Play Framework JPA Plugin', + 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', + 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', + 'redis_store' => 'Redis Session Store', + 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', + 'spring_boot_cli' => 'Spring Boot CLI', + 'tomcat' => 'Tomcat', + 'your_kit_profiler' => 'YourKit Profiler' + }.freeze + + PLATFORM_PATTERN = /\{platform\}/ + + + private_constant :ARCHITECTURE_PATTERN, :DEFAULT_REPOSITORY_ROOT_PATTERN, :NAME_MAPPINGS, + :PLATFORM_PATTERN + + def augment(raw, key, pattern, candidates, &block) + if raw.respond_to? :at + raw.map(&block) + elsif raw[:uri] =~ pattern + candidates.map do |candidate| + dup = raw.clone + dup[key] = candidate + dup[:uri] = raw[:uri].gsub pattern, candidate + + dup + end + else + raw + end + end + + def augment_architecture(raw) + augment(raw, :architecture, ARCHITECTURE_PATTERN, ARCHITECTURES) { |r| augment_architecture r } + end + + def augment_path(raw) + if raw.respond_to? :at + raw.map { |r| augment_path r } + else + raw[:uri] = "#{raw[:uri].chomp('/')}/index.yml" + raw + end + end + + def augment_platform(raw) + augment(raw, :platform, PLATFORM_PATTERN, PLATFORMS) { |r| augment_platform r } + end + + def augment_repository_root(raw) + augment(raw, :repository_root, DEFAULT_REPOSITORY_ROOT_PATTERN, [default_repository_root]) do |r| + augment_repository_root r + end + end + + def component_configuration(component_id) + configurations(component_id, configuration(component_id)) + end + + def component_ids + configuration('components').values.flatten.map { |component| component.split('::').last.snake_case } + end + + def configuration(id) + JavaBuildpack::Util::ConfigurationUtils.load(id, false, false) + end + + def configurations(component_id, configuration, sub_component_id = nil) + configurations = [] + + if repository_configuration?(configuration) + configuration['component_id'] = component_id + configuration['sub_component_id'] = sub_component_id if sub_component_id + configurations << configuration + else + configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } + end + + configurations + end + + def default_repository_root + configuration('repository')['default_repository_root'].chomp('/') + end + + def get_from_cache(cache, configuration, index_configuration) + cache.get(index_configuration[:uri]) do |f| + index = YAML.safe_load f + found_version = version(configuration, index) + + if found_version.nil? + raise "Unable to resolve version '#{configuration['version']}' for platform " \ + "'#{index_configuration[:platform]}'" + end + + return found_version.to_s, index[found_version.to_s] + end + end + + def dependency_versions + dependency_versions = [] + + cache = JavaBuildpack::Util::Cache::DownloadCache.new + configurations = component_ids.map { |component_id| component_configuration(component_id) }.flatten + + configurations.each do |configuration| + id = configuration['sub_component_id'] || configuration['component_id'] + + index_configuration(configuration).each do |index_configuration| + version, uri = get_from_cache(cache, configuration, index_configuration) + + + dependency_versions << { + 'id' => id, + 'name' => NAME_MAPPINGS[id] || 'UNKNOWN', + 'uri' => uri, + 'version' => version + } + end + end + + dependency_versions.sort_by { |dependency| dependency['id'] } + end + + def index_configuration(configuration) + [configuration['repository_root']] + .map { |r| { uri: r } } + .map { |r| augment_repository_root r } + .map { |r| augment_platform r } + .map { |r| augment_architecture r } + .map { |r| augment_path r }.flatten + end + + def repository_configuration?(configuration) + configuration['version'] && configuration['repository_root'] + end + + def version(configuration, index) + JavaBuildpack::Repository::VersionResolver + .resolve(JavaBuildpack::Util::TokenizedVersion.new(configuration['version']), index.keys) + end + + def versions + { + 'buildpack' => Package.version, + 'dependencies' => dependency_versions + } + end + + end + +end From ba02b95a0b85d3ed19a5eff062d0079cdc1a4310 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 May 2017 13:59:37 -0700 Subject: [PATCH 267/812] Rubocop Fixes --- rakelib/versions_task.rb | 50 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index ad3f468ea5..ff0ee30ff4 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -33,26 +33,11 @@ class VersionsTask < Rake::TaskLib def initialize JavaBuildpack::Logging::LoggerFactory.instance.setup "#{BUILD_DIR}/" - desc 'Display the versions of buildpack dependencies in human readable form' - task versions: [] do - v = versions - - puts Terminal::Table.new title: "Java Buildpack #{v['buildpack']}", - rows: v['dependencies'] - .sort_by { |dependency| dependency['name'] } - .map { |dependency| [dependency['name'], dependency['version']] } - end + version_task namespace 'versions' do - desc 'Display the versions of buildpack dependencies in JSON form' - task json: [] do - puts JSON.pretty_generate(versions) - end - - desc 'Display the versions of buildpack dependencies in YAML form' - task yaml: [] do - puts YAML.dump(versions) - end + version_json_task + version_yaml_task end end @@ -93,7 +78,6 @@ def initialize PLATFORM_PATTERN = /\{platform\}/ - private_constant :ARCHITECTURE_PATTERN, :DEFAULT_REPOSITORY_ROOT_PATTERN, :NAME_MAPPINGS, :PLATFORM_PATTERN @@ -192,7 +176,6 @@ def dependency_versions index_configuration(configuration).each do |index_configuration| version, uri = get_from_cache(cache, configuration, index_configuration) - dependency_versions << { 'id' => id, 'name' => NAME_MAPPINGS[id] || 'UNKNOWN', @@ -223,6 +206,33 @@ def version(configuration, index) .resolve(JavaBuildpack::Util::TokenizedVersion.new(configuration['version']), index.keys) end + def version_task + desc 'Display the versions of buildpack dependencies in human readable form' + task versions: [] do + v = versions + + rows = v['dependencies'] + .sort_by { |dependency| dependency['name'] } + .map { |dependency| [dependency['name'], dependency['version']] } + + puts Terminal::Table.new title: "Java Buildpack #{v['buildpack']}", rows: rows + end + end + + def version_json_task + desc 'Display the versions of buildpack dependencies in JSON form' + task json: [] do + puts JSON.pretty_generate(versions) + end + end + + def version_yaml_task + desc 'Display the versions of buildpack dependencies in YAML form' + task yaml: [] do + puts YAML.dump(versions) + end + end + def versions { 'buildpack' => Package.version, From d1a9e6e03a5541b95c5713b24511d2bda8ecac59 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 May 2017 14:35:17 -0700 Subject: [PATCH 268/812] Versions Output Polishing This change adds the unknown ID to the unknown name and sorts names ignoring case. --- rakelib/versions_task.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index ff0ee30ff4..cfd6f289b4 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -178,7 +178,7 @@ def dependency_versions dependency_versions << { 'id' => id, - 'name' => NAME_MAPPINGS[id] || 'UNKNOWN', + 'name' => NAME_MAPPINGS[id] || "UNKNOWN (#{id})", 'uri' => uri, 'version' => version } @@ -212,7 +212,7 @@ def version_task v = versions rows = v['dependencies'] - .sort_by { |dependency| dependency['name'] } + .sort_by { |dependency| dependency['name'].downcase } .map { |dependency| [dependency['name'], dependency['version']] } puts Terminal::Table.new title: "Java Buildpack #{v['buildpack']}", rows: rows From c9e39824a3d09b148d132b2b2edc41c1c545f7a0 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 May 2017 14:37:25 -0700 Subject: [PATCH 269/812] Additional Dependency Name --- rakelib/versions_task.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index cfd6f289b4..f03b15bb90 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -59,6 +59,7 @@ def initialize 'groovy' => 'Groovy', 'jre' => 'OpenJDK JRE', 'jrebel_agent' => 'JRebel Agent', + 'jvmkill_agent' => 'jvmkill Agent', 'lifecycle_support' => 'Tomcat Lifecycle Support', 'logging_support' => 'Tomcat Logging Support', 'luna_security_provider' => 'Gemalto Luna Security Provider', From 120a86ff6728353f39ac045e1b50e04b2a9d7677 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 8 May 2017 13:08:41 -0700 Subject: [PATCH 270/812] Move Non-Open Source Dependencies Previously, all dependencies for the buildpack were available at a Cloud Foundry Foundation controlled domain. Given recent guidance, dependencies that are not pure open source cannot be hosted at Foundation domains. This change moves the download locations of these non pure open source dependencies to a Pivotal domain. --- config/new_relic_agent.yml | 2 +- config/your_kit_profiler.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/new_relic_agent.yml b/config/new_relic_agent.yml index 534f23b6b5..6e409f962b 100644 --- a/config/new_relic_agent.yml +++ b/config/new_relic_agent.yml @@ -16,4 +16,4 @@ # Configuration for the New Relic framework --- version: 3.+ -repository_root: "{default.repository.root}/new-relic" +repository_root: "https://download.run.pivotal.io/new-relic" diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml index 609181e28b..973c9f489b 100644 --- a/config/your_kit_profiler.yml +++ b/config/your_kit_profiler.yml @@ -16,7 +16,7 @@ # JMX configuration --- version: 2017.+ -repository_root: "{default.repository.root}/your-kit/{platform}/{architecture}" +repository_root: "https://download.run.pivotal.io/your-kit/{platform}/{architecture}" enabled: false port: 10001 default_session_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); From f752ef0e3c0584ac3c7ee41a440179ec096f0ecb Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 8 May 2017 15:00:13 -0700 Subject: [PATCH 271/812] Dependency Updates --- Gemfile.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1989ed5844..bb249ea019 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,7 +7,7 @@ GEM crack (0.4.3) safe_yaml (~> 1.0.0) diff-lcs (1.3) - hashdiff (0.3.2) + hashdiff (0.3.4) parser (2.4.0.0) ast (~> 2.2) powerpack (0.1.1) @@ -16,34 +16,34 @@ GEM rake rake (12.0.0) redcarpet (3.4.0) - rspec (3.5.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-core (3.5.4) - rspec-support (~> 3.5.0) - rspec-expectations (3.5.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-mocks (3.5.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-support (3.5.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) rubocop (0.48.1) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.15.0) + rubocop-rspec (1.15.1) rubocop (>= 0.42.0) ruby-progressbar (1.8.1) rubyzip (1.2.1) safe_yaml (1.0.4) tee (1.0.0) - terminal-table (1.7.0) - unicode-display_width (~> 1.1) - unicode-display_width (1.2.1) + terminal-table (1.7.3) + unicode-display_width (~> 1.1.1) + unicode-display_width (1.1.3) webmock (3.0.1) addressable (>= 2.3.6) crack (>= 0.3.2) From 4fb3949e2b7a1f32c5a6dbf04fef7c7193f38932 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 8 May 2017 15:11:28 -0700 Subject: [PATCH 272/812] Quiet down Bundler during CI --- ci/package-test.sh | 2 +- ci/unit-test.sh | 2 +- ci/versions-json.sh | 2 +- ci/versions-yaml.sh | 2 +- ci/versions.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ci/package-test.sh b/ci/package-test.sh index f31f860e84..439c8e4f96 100755 --- a/ci/package-test.sh +++ b/ci/package-test.sh @@ -23,6 +23,6 @@ export LC_ALL=en_US.UTF-8 eval "$(rbenv init -)" pushd java-buildpack - bundle install + bundle install --quiet bundle exec rake package popd diff --git a/ci/unit-test.sh b/ci/unit-test.sh index c6498f58b5..215cefb442 100755 --- a/ci/unit-test.sh +++ b/ci/unit-test.sh @@ -23,6 +23,6 @@ export LC_ALL=en_US.UTF-8 eval "$(rbenv init -)" pushd java-buildpack - bundle install + bundle install --quiet bundle exec rake popd diff --git a/ci/versions-json.sh b/ci/versions-json.sh index fcb55ffdca..865af02df2 100755 --- a/ci/versions-json.sh +++ b/ci/versions-json.sh @@ -23,6 +23,6 @@ export LC_ALL=en_US.UTF-8 eval "$(rbenv init -)" pushd java-buildpack - bundle install + bundle install --quiet bundle exec rake versions:json popd diff --git a/ci/versions-yaml.sh b/ci/versions-yaml.sh index f8d0c51caf..70b8d61c46 100755 --- a/ci/versions-yaml.sh +++ b/ci/versions-yaml.sh @@ -23,6 +23,6 @@ export LC_ALL=en_US.UTF-8 eval "$(rbenv init -)" pushd java-buildpack - bundle install + bundle install --quiet bundle exec rake versions:yaml popd diff --git a/ci/versions.sh b/ci/versions.sh index c4decb0391..35ae58c16f 100755 --- a/ci/versions.sh +++ b/ci/versions.sh @@ -23,6 +23,6 @@ export LC_ALL=en_US.UTF-8 eval "$(rbenv init -)" pushd java-buildpack - bundle install + bundle install --quiet bundle exec rake versions popd From 99bdea87b972ed51d340fcf3edffe04a4715c695 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 10 May 2017 06:44:59 -0700 Subject: [PATCH 273/812] MariaDB Upgrade The 2.x line of the MariaDB JDBC driver is now available. This change updates the configuration to start using it. --- config/maria_db_jdbc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/maria_db_jdbc.yml b/config/maria_db_jdbc.yml index 58571c2bf1..b699f2758b 100644 --- a/config/maria_db_jdbc.yml +++ b/config/maria_db_jdbc.yml @@ -15,5 +15,5 @@ # Configuration for the MariaDB JDBC framework --- -version: 1.+ +version: 2.+ repository_root: "{default.repository.root}/mariadb-jdbc" From d06ca2c190a1b59fa49273520bcdc96f986658ca Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 15 May 2017 14:49:14 -0700 Subject: [PATCH 274/812] Polishing --- .idea/dictionaries/bhale.xml | 2 ++ .idea/runConfigurations/All_Tests__2_3_.xml | 2 +- .idea/runConfigurations/All_Tests__2_4_.xml | 2 +- .../Without_Integration_Tests__2_3_.xml | 2 +- .../Without_Integration_Tests__2_4_.xml | 2 +- java-buildpack.iml | 18 +++++++++--------- .../framework/new_relic_agent.rb | 8 ++++---- 7 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 0b69007560..dd635b2f2a 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -8,6 +8,7 @@ argv atpack bootclasspath + buildpack cacert chrystoki cklog @@ -61,6 +62,7 @@ myhost mypass myuser + newrelic newrelicagent overweaving pathnames diff --git a/.idea/runConfigurations/All_Tests__2_3_.xml b/.idea/runConfigurations/All_Tests__2_3_.xml index ae92d24c95..16757fc1af 100644 --- a/.idea/runConfigurations/All_Tests__2_3_.xml +++ b/.idea/runConfigurations/All_Tests__2_3_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_4_.xml b/.idea/runConfigurations/All_Tests__2_4_.xml index 1ad04203f5..02bfb110fc 100644 --- a/.idea/runConfigurations/All_Tests__2_4_.xml +++ b/.idea/runConfigurations/All_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml index aa696c0cea..e1ba536bb0 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml index a2a4c83c9c..567a5e49a4 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/java-buildpack.iml b/java-buildpack.iml index 90a0374579..4c84f30c7a 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -272,26 +272,26 @@ - + - - - - - + + + + + - + - - + + diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 477db07e0a..06fcf9b847 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -30,8 +30,8 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] - java_opts = @droplet.java_opts + credentials = @application.services.find_service(FILTER)['credentials'] + java_opts = @droplet.java_opts configuration = {} apply_configuration(credentials, configuration) @@ -61,9 +61,9 @@ def supports? private_constant :FILTER, :LICENSE_KEY, :LICENSE_KEY_USER def apply_configuration(credentials, configuration) - configuration['log_file_name'] = 'STDOUT' + configuration['log_file_name'] = 'STDOUT' configuration[LICENSE_KEY_USER] = credentials[LICENSE_KEY] - configuration['app_name'] = @application.details['application_name'] + configuration['app_name'] = @application.details['application_name'] end def apply_user_configuration(credentials, configuration) From 3e5b72e8f1efa37f107b373b9cf4d76677eeb2d0 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 16 May 2017 13:22:07 -0700 Subject: [PATCH 275/812] Polishing --- docs/framework-new_relic_agent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-new_relic_agent.md b/docs/framework-new_relic_agent.md index 26f2810e0f..252b34f8c4 100644 --- a/docs/framework-new_relic_agent.md +++ b/docs/framework-new_relic_agent.md @@ -44,5 +44,5 @@ The framework can also be configured by overlaying a set of resources on the def [`config/new_relic_agent.yml`]: ../config/new_relic_agent.yml [New Relic Service]: https://newrelic.com [repositories]: extending-repositories.md -[this listing]: http://download.pivotal.io.s3.amazonaws.com/new-relic/index.yml +[this listing]: https://download.run.pivotal.io/new-relic/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering From 7f4935bb5483147dd3b5a7c70f047774835c20ce Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 23 May 2017 12:17:00 -0700 Subject: [PATCH 276/812] Container Security Provider This change adds a Container Security Provider to the buildpack. This security provider is aware of container identity in a Cloud Foundry container as defined by a private key and certificate. As part of the addition of this functionality, extensions were made to the Droplet Public API to allow components to contribute both extension directories and security providers. This resulted in the update of the Dyadic, Luna, and ProtectApp providers. --- .idea/codeStyleSettings.xml | 1 + .rubocop.yml | 2 +- config/components.yml | 1 + ...re.yml => container_security_provider.yml} | 7 +- lib/java_buildpack/buildpack.rb | 26 +- .../component/additional_libraries.rb | 2 +- lib/java_buildpack/component/droplet.rb | 22 +- .../component/extension_directories.rb | 46 + .../component/security_providers.rb | 42 + .../framework/container_security_provider.rb | 48 + .../framework/dyadic_ekm_security_provider.rb | 18 +- .../framework/luna_security_provider.rb | 12 +- .../protect_app_security_provider.rb | 15 +- lib/java_buildpack/jre/open_jdk_like.rb | 4 +- .../jre/open_jdk_like_security_providers.rb | 95 ++ .../java.security | 1 - .../luna_security_provider/java.security | 1 - .../java.security | 1 - spec/droplet_helper.rb | 15 +- spec/fixtures/java.security | 826 ++++++++++++++++++ .../stub-container-security-provider.jar | Bin 0 -> 341 bytes spec/java_buildpack/component/droplet_spec.rb | 8 + .../component/extension_directories_spec.rb | 50 ++ .../component/security_providers_spec.rb | 45 + .../container_security_provider_spec.rb | 40 + .../dyadic_ekm_security_provider_spec.rb | 24 +- .../framework/luna_security_provider_spec.rb | 16 +- .../protect_app_security_provider_spec.rb | 23 +- .../open_jdk_like_security_providers_spec.rb | 85 ++ spec/java_buildpack/jre/open_jdk_like_spec.rb | 3 + 30 files changed, 1397 insertions(+), 82 deletions(-) rename config/{container_certificate_trust_store.yml => container_security_provider.yml} (80%) create mode 100644 lib/java_buildpack/component/extension_directories.rb create mode 100644 lib/java_buildpack/component/security_providers.rb create mode 100644 lib/java_buildpack/framework/container_security_provider.rb create mode 100644 lib/java_buildpack/jre/open_jdk_like_security_providers.rb delete mode 100644 resources/dyadic_ekm_security_provider/java.security delete mode 100644 resources/luna_security_provider/java.security delete mode 100644 resources/protect_app_security_provider/java.security create mode 100644 spec/fixtures/java.security create mode 100644 spec/fixtures/stub-container-security-provider.jar create mode 100644 spec/java_buildpack/component/extension_directories_spec.rb create mode 100644 spec/java_buildpack/component/security_providers_spec.rb create mode 100644 spec/java_buildpack/framework/container_security_provider_spec.rb create mode 100644 spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml index 72613537be..8daae40f5e 100644 --- a/.idea/codeStyleSettings.xml +++ b/.idea/codeStyleSettings.xml @@ -11,6 +11,7 @@ diff --git a/lib/java_buildpack/component/modular_component.rb b/lib/java_buildpack/component/modular_component.rb index c738ee916a..2faab8d72d 100644 --- a/lib/java_buildpack/component/modular_component.rb +++ b/lib/java_buildpack/component/modular_component.rb @@ -69,7 +69,7 @@ def command # @param [Hash] context the context of the component # @return [Array] a collection of +BaseComponent+s that make up the sub_components of this # component - def sub_components(_context) + def sub_components(context) raise "Method 'sub_components' must be defined" end From 28c1833976770bd2769bbabbd3355b539bb88a32 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 2 Jun 2017 14:37:33 -0700 Subject: [PATCH 288/812] Polishing --- lib/java_buildpack/component/modular_component.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/component/modular_component.rb b/lib/java_buildpack/component/modular_component.rb index 2faab8d72d..c738ee916a 100644 --- a/lib/java_buildpack/component/modular_component.rb +++ b/lib/java_buildpack/component/modular_component.rb @@ -69,7 +69,7 @@ def command # @param [Hash] context the context of the component # @return [Array] a collection of +BaseComponent+s that make up the sub_components of this # component - def sub_components(context) + def sub_components(_context) raise "Method 'sub_components' must be defined" end From 703b5ca5738c7db78f052d480098717682d5c41d Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 6 Jun 2017 12:52:18 -0700 Subject: [PATCH 289/812] Metric Writer Framework This change adds a framework for writing Spring Boot metrics into a Metric Forwarder service. [resolves #440] --- README.md | 1 + config/components.yml | 3 +- config/metric_writer.yml | 19 +++++ docs/framework-metric_writer.md | 40 ++++++++++ .../framework/container_security_provider.rb | 2 - lib/java_buildpack/framework/metric_writer.rb | 62 +++++++++++++++ rakelib/versions_task.rb | 1 + spec/application_helper.rb | 3 +- spec/fixtures/stub-metric-writer.jar | 0 .../framework/metric_writer_spec.rb | 79 +++++++++++++++++++ 10 files changed, 206 insertions(+), 4 deletions(-) create mode 100644 config/metric_writer.yml create mode 100644 docs/framework-metric_writer.md create mode 100644 lib/java_buildpack/framework/metric_writer.rb create mode 100644 spec/fixtures/stub-metric-writer.jar create mode 100644 spec/java_buildpack/framework/metric_writer_spec.rb diff --git a/README.md b/README.md index 8eb07a199e..0fb2e5b962 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [JMX](docs/framework-jmx.md) ([Configuration](docs/framework-jmx.md#configuration)) * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) + * [Metric Writer](docs/framework-metric_writer.md) ([Configuration](docs/framework-metric_writer.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) * [Play Framework JPA Plugin](docs/framework-play_framework_jpa_plugin.md) ([Configuration](docs/framework-play_framework_jpa_plugin.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 6d56bc7aff..21f45ab93c 100644 --- a/config/components.yml +++ b/config/components.yml @@ -41,6 +41,7 @@ frameworks: - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::ContainerSecurityProvider" - "JavaBuildpack::Framework::Debug" + - "JavaBuildpack::Framework::DyadicEkmSecurityProvider" - "JavaBuildpack::Framework::DynatraceAppmonAgent" - "JavaBuildpack::Framework::DynatraceOneAgent" - "JavaBuildpack::Framework::GoogleStackdriverDebugger" @@ -48,8 +49,8 @@ frameworks: - "JavaBuildpack::Framework::Jmx" - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::LunaSecurityProvider" - - "JavaBuildpack::Framework::DyadicEkmSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" + - "JavaBuildpack::Framework::MetricWriter" - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration" - "JavaBuildpack::Framework::PlayFrameworkJPAPlugin" diff --git a/config/metric_writer.yml b/config/metric_writer.yml new file mode 100644 index 0000000000..a69d3a2b19 --- /dev/null +++ b/config/metric_writer.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Metric Writer configuration +--- +version: 1.+ +repository_root: "{default.repository.root}/metric-writer" diff --git a/docs/framework-metric_writer.md b/docs/framework-metric_writer.md new file mode 100644 index 0000000000..6aa8cbaf94 --- /dev/null +++ b/docs/framework-metric_writer.md @@ -0,0 +1,40 @@ +# Metric Writer Framework +The Metric Writer Framework causes an application to be automatically configured to work with a bound Metrics Forwarder Service. + + + + + + + + + +
Detection CriterionExistence of a single bound Metrics Forwarder service. +
    +
  • Existence of a Metrics Forwarder service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has metrics-forwarder as a substring.
  • +
+
Tagsmetric_writer=<version>
+Tags are printed to standard output by the buildpack detect script + +The credential payload of the service may contain the following entries: + +| Name | Description +| ---- | ----------- +| `access_key` | The access key used to authenticate agains the endpoint +| `hostname` | The hostname of the endpoint + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/metric_writer.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Metric Writer repository index ([details][repositories]). +| `version` | The version of Metric Writer to use. Candidate versions can be found in [this listing][]. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[`config/metric_writer.yml`]: ../config/metric_writer.yml +[repositories]: extending-repositories.md +[this listing]: https://java-buildpack.cloudfoundry.org/metric-writer/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/container_security_provider.rb b/lib/java_buildpack/framework/container_security_provider.rb index 1a674d885a..52ceba930e 100644 --- a/lib/java_buildpack/framework/container_security_provider.rb +++ b/lib/java_buildpack/framework/container_security_provider.rb @@ -15,14 +15,12 @@ require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' -require 'java_buildpack/util/qualify_path' module JavaBuildpack module Framework # Encapsulates the functionality for contributing a container-based security provider to an application. class ContainerSecurityProvider < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Util # (see JavaBuildpack::Component::BaseComponent#compile) def compile diff --git a/lib/java_buildpack/framework/metric_writer.rb b/lib/java_buildpack/framework/metric_writer.rb new file mode 100644 index 0000000000..b410e87e8d --- /dev/null +++ b/lib/java_buildpack/framework/metric_writer.rb @@ -0,0 +1,62 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for contributing a container-based security provider to an application. + class MetricWriter < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + credentials = @application.services.find_service(FILTER)['credentials'] + + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + @droplet.java_opts + .add_system_property('cloudfoundry.metrics.accessToken', credentials[ACCESS_KEY]) + .add_system_property('cloudfoundry.metrics.applicationId', @application.details['application_id']) + .add_system_property('cloudfoundry.metrics.endpoint', "https://#{credentials[HOSTNAME]}") + .add_system_property('cloudfoundry.metrics.instanceId', '$CF_INSTANCE_GUID') + .add_system_property('cloudfoundry.metrics.instanceIndex', '$CF_INSTANCE_INDEX') + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, ACCESS_KEY, HOSTNAME + end + + ACCESS_KEY = 'access_key'.freeze + + FILTER = /metrics-forwarder/ + + HOSTNAME = 'hostname'.freeze + + private_constant :ACCESS_KEY, :FILTER, :HOSTNAME + + end + + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index fcd892c229..436e8b6f81 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -64,6 +64,7 @@ def initialize 'luna_security_provider' => 'Gemalto Luna Security Provider', 'maria_db_jdbc' => 'MariaDB JDBC Driver', 'memory_calculator' => 'Memory Calculator', + 'metric_writer' => 'Metric Writer', 'new_relic_agent' => 'New Relic Agent', 'play_framework_auto_reconfiguration' => 'Play Framework Auto-reconfiguration', 'play_framework_jpa_plugin' => 'Play Framework JPA Plugin', diff --git a/spec/application_helper.rb b/spec/application_helper.rb index df7f4aca51..d3b320c7db 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -46,7 +46,8 @@ let(:services) { application.services } let(:vcap_application) do - { 'application_name' => 'test-application-name', + { 'application_id' => 'test-application-id', + 'application_name' => 'test-application-name', 'application_version' => 'test-application-version' } end diff --git a/spec/fixtures/stub-metric-writer.jar b/spec/fixtures/stub-metric-writer.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/metric_writer_spec.rb b/spec/java_buildpack/framework/metric_writer_spec.rb new file mode 100644 index 0000000000..14b001a06f --- /dev/null +++ b/spec/java_buildpack/framework/metric_writer_spec.rb @@ -0,0 +1,79 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/metric_writer' + +describe JavaBuildpack::Framework::MetricWriter do + include_context 'component_helper' + + it 'does not detect without metric-forwarder service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?).with(/metrics-forwarder/, 'access_key', 'hostname').and_return(true) + end + + it 'detects with metric-forwarder service' do + expect(component.detect).to eq("metric-writer=#{version}") + end + + it 'downloads Metric Writer JAR', + cache_fixture: 'stub-metric-writer.jar' do + + component.compile + + expect(sandbox + "metric_writer-#{version}.jar").to exist + end + + it 'adds the metric writer to the additional libraries in compile when needed', + cache_fixture: 'stub-metric-writer.jar' do + + component.compile + + expect(additional_libraries).to include(sandbox + "metric_writer-#{version}.jar") + end + + it 'adds the metric writer to the additional libraries in release when needed', + cache_fixture: 'stub-metric-writer.jar' do + + allow(services).to receive(:find_service).and_return('credentials' => { 'access_key' => 'test-access-key', + 'hostname' => 'test-hostname' }) + + component.release + + expect(additional_libraries).to include(sandbox + "metric_writer-#{version}.jar") + end + + it 'updates JAVA_OPTS' do + allow(services).to receive(:find_service).and_return('credentials' => { 'access_key' => 'test-access-key', + 'hostname' => 'test-hostname' }) + + component.release + + expect(java_opts).to include('-Dcloudfoundry.metrics.accessToken=test-access-key') + expect(java_opts).to include('-Dcloudfoundry.metrics.applicationId=test-application-id') + expect(java_opts).to include('-Dcloudfoundry.metrics.endpoint=https://test-hostname') + expect(java_opts).to include('-Dcloudfoundry.metrics.instanceId=$CF_INSTANCE_GUID') + expect(java_opts).to include('-Dcloudfoundry.metrics.instanceIndex=$CF_INSTANCE_INDEX') + end + + end + +end From 834c9785f440b1d3854c043be4e56f5924564cd1 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 6 Jun 2017 14:35:42 -0700 Subject: [PATCH 290/812] no_proxy support This change adds no_proxy support to the DownloadCache. This will allow certain hosts to be skipped when using proxies. [resolves #438] --- .../util/cache/download_cache.rb | 9 +++++- .../util/cache/download_cache_spec.rb | 32 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 96fee72b1f..f67fd742e4 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -265,8 +265,15 @@ def http_options(rich_uri) http_options end + def no_proxy?(uri) + hosts = (ENV['no_proxy'] || ENV['NO_PROXY'] || '').split ',' + hosts.any? { |host| uri.host.end_with? host } + end + def proxy(uri) - proxy_uri = if secure?(uri) + proxy_uri = if no_proxy?(uri) + URI.parse('') + elsif secure?(uri) URI.parse(ENV['https_proxy'] || ENV['HTTPS_PROXY'] || '') else URI.parse(ENV['http_proxy'] || ENV['HTTP_PROXY'] || '') diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index b418898974..b076e7021f 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -250,6 +250,38 @@ end + context do + let(:environment) { { 'NO_PROXY' => '127.0.0.1,localhost,foo-uri,.foo-uri', 'HTTPS_PROXY' => 'http://proxy:9000' } } + + it 'does not use proxy if host in NO_PROXY' do + stub_request(:get, uri_secure) + .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', + 'Last-Modified' => 'foo-last-modified' }) + + allow(Net::HTTP).to receive(:Proxy).and_call_original + expect(Net::HTTP).not_to have_received(:Proxy).with('proxy', 9000, nil, nil) + + download_cache.get(uri_secure) {} + end + + end + + context do + let(:environment) { { 'no_proxy' => '127.0.0.1,localhost,foo-uri,.foo-uri', 'https_proxy' => 'http://proxy:9000' } } + + it 'does not use proxy if host in no_proxy' do + stub_request(:get, uri_secure) + .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', + 'Last-Modified' => 'foo-last-modified' }) + + allow(Net::HTTP).to receive(:Proxy).and_call_original + expect(Net::HTTP).not_to have_received(:Proxy).with('proxy', 9000, nil, nil) + + download_cache.get(uri_secure) {} + end + + end + it 'does not use ca_file if the URL is not secure and directory does not exist' do stub_request(:get, uri) .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) From 0bb3e9dbaca8a124fff02e60ec6a937bbc6c99e1 Mon Sep 17 00:00:00 2001 From: Britta Date: Wed, 7 Jun 2017 07:44:33 -0700 Subject: [PATCH 291/812] Additional README detail This change adds a note to the README that MariaDB support also includes MySQL support. [#442] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fb2e5b962..dbb6f4a70a 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) * [JMX](docs/framework-jmx.md) ([Configuration](docs/framework-jmx.md#configuration)) * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) - * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) + * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) (also supports MySQL) * [Metric Writer](docs/framework-metric_writer.md) ([Configuration](docs/framework-metric_writer.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) From 529e2e13fba1d4dc8d059f62ee66a7e579ddf1fd Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 9 Jun 2017 10:04:45 -0700 Subject: [PATCH 292/812] Update Metric Writer to New Payload This change updates the Metric Writer framework to handle the new credentials payload. --- docs/framework-metric_writer.md | 2 +- lib/java_buildpack/framework/metric_writer.rb | 10 +++++----- spec/java_buildpack/framework/metric_writer_spec.rb | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/framework-metric_writer.md b/docs/framework-metric_writer.md index 6aa8cbaf94..0ae3933225 100644 --- a/docs/framework-metric_writer.md +++ b/docs/framework-metric_writer.md @@ -21,7 +21,7 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- | `access_key` | The access key used to authenticate agains the endpoint -| `hostname` | The hostname of the endpoint +| `endpoint` | The endpoint ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/metric_writer.rb b/lib/java_buildpack/framework/metric_writer.rb index b410e87e8d..a2ace91cc5 100644 --- a/lib/java_buildpack/framework/metric_writer.rb +++ b/lib/java_buildpack/framework/metric_writer.rb @@ -36,7 +36,7 @@ def release @droplet.java_opts .add_system_property('cloudfoundry.metrics.accessToken', credentials[ACCESS_KEY]) .add_system_property('cloudfoundry.metrics.applicationId', @application.details['application_id']) - .add_system_property('cloudfoundry.metrics.endpoint', "https://#{credentials[HOSTNAME]}") + .add_system_property('cloudfoundry.metrics.endpoint', credentials[ENDPOINT]) .add_system_property('cloudfoundry.metrics.instanceId', '$CF_INSTANCE_GUID') .add_system_property('cloudfoundry.metrics.instanceIndex', '$CF_INSTANCE_INDEX') end @@ -45,16 +45,16 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, ACCESS_KEY, HOSTNAME + @application.services.one_service? FILTER, ACCESS_KEY, ENDPOINT end ACCESS_KEY = 'access_key'.freeze - FILTER = /metrics-forwarder/ + ENDPOINT = 'endpoint'.freeze - HOSTNAME = 'hostname'.freeze + FILTER = /metrics-forwarder/ - private_constant :ACCESS_KEY, :FILTER, :HOSTNAME + private_constant :ACCESS_KEY, :ENDPOINT, :FILTER end diff --git a/spec/java_buildpack/framework/metric_writer_spec.rb b/spec/java_buildpack/framework/metric_writer_spec.rb index 14b001a06f..f18362228a 100644 --- a/spec/java_buildpack/framework/metric_writer_spec.rb +++ b/spec/java_buildpack/framework/metric_writer_spec.rb @@ -27,7 +27,7 @@ context do before do - allow(services).to receive(:one_service?).with(/metrics-forwarder/, 'access_key', 'hostname').and_return(true) + allow(services).to receive(:one_service?).with(/metrics-forwarder/, 'access_key', 'endpoint').and_return(true) end it 'detects with metric-forwarder service' do @@ -54,7 +54,7 @@ cache_fixture: 'stub-metric-writer.jar' do allow(services).to receive(:find_service).and_return('credentials' => { 'access_key' => 'test-access-key', - 'hostname' => 'test-hostname' }) + 'endpoint' => 'https://test-endpoint' }) component.release @@ -63,13 +63,13 @@ it 'updates JAVA_OPTS' do allow(services).to receive(:find_service).and_return('credentials' => { 'access_key' => 'test-access-key', - 'hostname' => 'test-hostname' }) + 'endpoint' => 'https://test-endpoint' }) component.release expect(java_opts).to include('-Dcloudfoundry.metrics.accessToken=test-access-key') expect(java_opts).to include('-Dcloudfoundry.metrics.applicationId=test-application-id') - expect(java_opts).to include('-Dcloudfoundry.metrics.endpoint=https://test-hostname') + expect(java_opts).to include('-Dcloudfoundry.metrics.endpoint=https://test-endpoint') expect(java_opts).to include('-Dcloudfoundry.metrics.instanceId=$CF_INSTANCE_GUID') expect(java_opts).to include('-Dcloudfoundry.metrics.instanceIndex=$CF_INSTANCE_INDEX') end From 9fdd1df37361f5222bb363608f740c45bcc0de5b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 12 Jun 2017 09:23:35 -0700 Subject: [PATCH 293/812] Polishing --- docs/debugging-the-buildpack.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/debugging-the-buildpack.md b/docs/debugging-the-buildpack.md index 354d351a6f..72cd22f1f4 100644 --- a/docs/debugging-the-buildpack.md +++ b/docs/debugging-the-buildpack.md @@ -125,7 +125,7 @@ JBP_LOG_LEVEL=DEBUG /bin/compile . $TMPDIR JBP_LOG_LEVEL=DEBUG /bin/release . ``` -##Aliases +## Aliases Running the different stages of the buildpack lifecycle can be made simpler with the use of aliases and an environment variable to point at your local copy of the buildpack. The examples below pass in `.` to the scripts assuming you are calling them from the local working directory. From c7148c3be2d75dc892818e173433fa51ff6e7acf Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 13 Jun 2017 10:56:56 -0700 Subject: [PATCH 294/812] Heap Dump to Volume Service This change adds support for configuring the jvmkill agent to create terminal heap dumps into volume services with a name, label, or tag containing heap- dump. If that service does not exist, the agent continues to print the heap histogram to the console. [resolves #439] --- docs/jre-open_jdk_jre.md | 56 ++++++++++++++-- docs/jre-oracle_jre.md | 55 ++++++++++++++-- docs/jre-zulu_jre.md | 59 +++++++++++++++-- lib/java_buildpack/component/services.rb | 35 ++++++++-- lib/java_buildpack/jre/jvmkill_agent.rb | 31 ++++++++- spec/application_helper.rb | 4 +- .../java_buildpack/component/services_spec.rb | 65 +++++++++++++++++++ spec/java_buildpack/jre/jvmkill_agent_spec.rb | 13 ++++ 8 files changed, 293 insertions(+), 25 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 6a25e34bcb..a0b4385cb5 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -4,11 +4,15 @@ The OpenJDK JRE provides Java runtimes from the [OpenJDK][] project. Versions o - + - +
Detection CriterionUnconditionalUnconditional. Existence of a single bound Volume Service will result in Terminal heap dumps being written. +
    +
  • Existence of a Volume Service service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has heap-dump as a substring.
  • +
+
Tagsopen-jdk=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩open-jdk=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩, jvmkill=⟨version⟩
Tags are printed to standard output by the buildpack detect script @@ -20,9 +24,11 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | Name | Description | ---- | ----------- +| `jre.repository_root` | The URL of the OpenJDK repository index ([details][repositories]). +| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [mountainlion][] and [trusty][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [mountainlion][jvmkill-mountainlion] and [trusty][jvmkill-trusty]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". -| `repository_root` | The URL of the OpenJDK repository index ([details][repositories]). -| `version` | The version of Java runtime to use. Candidate versions can be found in the listings for [mountainlion][], [precise][], and [trusty][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. ### Additional Resources The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/open_jdk_jre` directory in the buildpack fork. @@ -33,6 +39,42 @@ To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resource #### Custom CA Certificates To add custom SSL certificates, add your `cacerts` file to `resources/open_jdk_jre/lib/security/cacerts`. This file will be overlayed onto the OpenJDK distribution. +### `jvmkill` +The `jvmkill` agent runs when an application has experience a resource exhaustion event. When this event occurs, the agent will print out a histogram of the first 100 largest types by total number of bytes. + +```plain +Resource exhaustion event: the JVM was unable to allocate memory from the heap. +ResourceExhausted! (1/0) +| Instance Count | Total Bytes | Class Name | +| 18273 | 313157136 | [B | +| 47806 | 7648568 | [C | +| 14635 | 1287880 | Ljava/lang/reflect/Method; | +| 46590 | 1118160 | Ljava/lang/String; | +| 8413 | 938504 | Ljava/lang/Class; | +| 28573 | 914336 | Ljava/util/concurrent/ConcurrentHashMap$Node; | +``` + +It will also print out a summary of all of the memory spaces in the JVM. + +```plain +Memory usage: + Heap memory: init 65011712, used 332392888, committed 351797248, max 351797248 + Non-heap memory: init 2555904, used 63098592, committed 64815104, max 377790464 +Memory pool usage: + Code Cache: init 2555904, used 14702208, committed 15007744, max 251658240 + PS Eden Space: init 16252928, used 84934656, committed 84934656, max 84934656 + PS Survivor Space: init 2621440, used 0, committed 19398656, max 19398656 + Compressed Class Space: init 0, used 5249512, committed 5505024, max 19214336 + Metaspace: init 0, used 43150616, committed 44302336, max 106917888 + PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 +``` + +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `"/-/-/--.hprof` + +```plain +Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39-b546-41d9-8095-9a45fa65df9e/java-main-application-892f20ab-9a53-441d-be3e-72c38f2a1055/0-2017-06-13T18:31:29+0000-7b23124e-7f0f-4a08-457b-60802d0a7326.hprof +``` + ### Memory The total available memory for the application's container is specified when an application is pushed. The Java buildpack uses this value to control the JRE's use of various @@ -84,7 +126,7 @@ The container's total available memory is allocated into heap, metaspace and com direct memory, and stack memory settings. The memory calculation is described in more detail in the [Memory Calculator's README]. - + The inputs to the memory calculation, except the container's total memory (which is unknown at staging time), are logged during staging, for example: ``` Loaded Classes: 13974, Threads: 300, JAVA_OPTS: '' @@ -105,10 +147,12 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [`config/open_jdk_jre.yml`]: ../config/open_jdk_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[jvmkill-mountainlion]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/mountainlion/x86_64/index.yml +[jvmkill-trusty]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/trusty/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [mountainlion]: http://download.pivotal.io.s3.amazonaws.com/openjdk/mountainlion/x86_64/index.yml [OpenJDK]: http://openjdk.java.net -[precise]: http://download.pivotal.io.s3.amazonaws.com/openjdk/precise/x86_64/index.yml [repositories]: extending-repositories.md [trusty]: http://download.pivotal.io.s3.amazonaws.com/openjdk/trusty/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering +[Volume Service]: https://docs.cloudfoundry.org/devguide/services/using-vol-services.html diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 19ba348fe8..b1edb8d005 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -4,11 +4,15 @@ The Oracle JRE provides Java runtimes from [Oracle][] project. No versions of t - + - +
Detection CriterionUnconditionalUnconditional. Existence of a single bound Volume Service will result in Terminal heap dumps being written. +
    +
  • Existence of a Volume Service service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has heap-dump as a substring.
  • +
+
Tagsoracle=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩oracle=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩, jvmkill=⟨version⟩
Tags are printed to standard output by the buildpack detect script @@ -36,9 +40,11 @@ To use Oracle JRE instead of OpenJDK without forking java-buildpack, set environ | Name | Description | ---- | ----------- +| `jre.repository_root` | The URL of the Oracle repository index ([details][repositories]). +| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [mountainlion][jvmkill-mountainlion] and [trusty][jvmkill-trusty]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". -| `repository_root` | The URL of the Oracle repository index ([details][repositories]). -| `version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. ### Additional Resources The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/oracle_jre` directory in the buildpack fork. @@ -49,6 +55,42 @@ To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resource #### Custom CA Certificates To add custom SSL certificates, add your `cacerts` file to `resources/oracle_jre/lib/security/cacerts`. This file will be overlayed onto the Oracle distribution. +### `jvmkill` +The `jvmkill` agent runs when an application has experience a resource exhaustion event. When this event occurs, the agent will print out a histogram of the first 100 largest types by total number of bytes. + +```plain +Resource exhaustion event: the JVM was unable to allocate memory from the heap. +ResourceExhausted! (1/0) +| Instance Count | Total Bytes | Class Name | +| 18273 | 313157136 | [B | +| 47806 | 7648568 | [C | +| 14635 | 1287880 | Ljava/lang/reflect/Method; | +| 46590 | 1118160 | Ljava/lang/String; | +| 8413 | 938504 | Ljava/lang/Class; | +| 28573 | 914336 | Ljava/util/concurrent/ConcurrentHashMap$Node; | +``` + +It will also print out a summary of all of the memory spaces in the JVM. + +```plain +Memory usage: + Heap memory: init 65011712, used 332392888, committed 351797248, max 351797248 + Non-heap memory: init 2555904, used 63098592, committed 64815104, max 377790464 +Memory pool usage: + Code Cache: init 2555904, used 14702208, committed 15007744, max 251658240 + PS Eden Space: init 16252928, used 84934656, committed 84934656, max 84934656 + PS Survivor Space: init 2621440, used 0, committed 19398656, max 19398656 + Compressed Class Space: init 0, used 5249512, committed 5505024, max 19214336 + Metaspace: init 0, used 43150616, committed 44302336, max 106917888 + PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 +``` + +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `"/-/-/--.hprof` + +```plain +Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39-b546-41d9-8095-9a45fa65df9e/java-main-application-892f20ab-9a53-441d-be3e-72c38f2a1055/0-2017-06-13T18:31:29+0000-7b23124e-7f0f-4a08-457b-60802d0a7326.hprof +``` + ### Memory The total available memory for the application's container is specified when an application is pushed. The Java buildpack uses this value to control the JRE's use of various @@ -100,7 +142,7 @@ The container's total available memory is allocated into heap, metaspace and com direct memory, and stack memory settings. The memory calculation is described in more detail in the [Memory Calculator's README]. - + The inputs to the memory calculation, except the container's total memory (which is unknown at staging time), are logged during staging, for example: ``` Loaded Classes: 13974, Threads: 300, JAVA_OPTS: '' @@ -122,8 +164,11 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [`config/oracle_jre.yml`]: ../config/oracle_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[jvmkill-mountainlion]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/mountainlion/x86_64/index.yml +[jvmkill-trusty]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/trusty/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [OpenJDK JRE]: jre-open_jdk_jre.md [Oracle]: http://www.oracle.com/technetwork/java/index.html [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering +[Volume Service]: https://docs.cloudfoundry.org/devguide/services/using-vol-services.html diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index 5e8f7f356a..8e2e21a405 100755 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -4,11 +4,15 @@ Azul Zulu JRE provides Java runtimes developed by Azul team. Versions of Java f - + - +
Detection CriterionUnconditionalUnconditional. Existence of a single bound Volume Service will result in Terminal heap dumps being written. +
    +
  • Existence of a Volume Service service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has heap-dump as a substring.
  • +
+
Tagsopen-jdk-like-jre=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩open-jdk-like-jre=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩, jvmkill=⟨version⟩
Tags are printed to standard output by the buildpack detect script. @@ -27,9 +31,11 @@ To use Zulu JRE instead of OpenJDK without forking java-buildpack, set environme | Name | Description | ---- | ----------- +| `jre.repository_root` | The URL of the Zulu repository index ([details][repositories]). +| `jre.version` | The version of Java runtime to use. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [mountainlion][jvmkill-mountainlion] and [trusty][jvmkill-trusty]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". -| `repository_root` | The URL of the Zulu repository index ([details][repositories]). -| `version` | The version of Java runtime to use. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. ### Additional Resources The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/zulu_jre` directory in the buildpack fork. @@ -40,6 +46,42 @@ To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resource #### Custom CA Certificates To add custom SSL certificates, add your `cacerts` file to `resources/zulu_jre/lib/security/cacerts`. This file will be overlayed onto the Zulu distribution. +### `jvmkill` +The `jvmkill` agent runs when an application has experience a resource exhaustion event. When this event occurs, the agent will print out a histogram of the first 100 largest types by total number of bytes. + +```plain +Resource exhaustion event: the JVM was unable to allocate memory from the heap. +ResourceExhausted! (1/0) +| Instance Count | Total Bytes | Class Name | +| 18273 | 313157136 | [B | +| 47806 | 7648568 | [C | +| 14635 | 1287880 | Ljava/lang/reflect/Method; | +| 46590 | 1118160 | Ljava/lang/String; | +| 8413 | 938504 | Ljava/lang/Class; | +| 28573 | 914336 | Ljava/util/concurrent/ConcurrentHashMap$Node; | +``` + +It will also print out a summary of all of the memory spaces in the JVM. + +```plain +Memory usage: + Heap memory: init 65011712, used 332392888, committed 351797248, max 351797248 + Non-heap memory: init 2555904, used 63098592, committed 64815104, max 377790464 +Memory pool usage: + Code Cache: init 2555904, used 14702208, committed 15007744, max 251658240 + PS Eden Space: init 16252928, used 84934656, committed 84934656, max 84934656 + PS Survivor Space: init 2621440, used 0, committed 19398656, max 19398656 + Compressed Class Space: init 0, used 5249512, committed 5505024, max 19214336 + Metaspace: init 0, used 43150616, committed 44302336, max 106917888 + PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 +``` + +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `"/-/-/--.hprof` + +```plain +Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39-b546-41d9-8095-9a45fa65df9e/java-main-application-892f20ab-9a53-441d-be3e-72c38f2a1055/0-2017-06-13T18:31:29+0000-7b23124e-7f0f-4a08-457b-60802d0a7326.hprof +``` + ### Memory The total available memory for the application's container is specified when an application is pushed. The Java buildpack uses this value to control the JRE's use of various @@ -91,7 +133,7 @@ The container's total available memory is allocated into heap, metaspace and com direct memory, and stack memory settings. The memory calculation is described in more detail in the [Memory Calculator's README]. - + The inputs to the memory calculation, except the container's total memory (which is unknown at staging time), are logged during staging, for example: ``` Loaded Classes: 13974, Threads: 300, JAVA_OPTS: '' @@ -111,10 +153,13 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [`config/components.yml`]: ../config/components.yml [`config/zulu_jre.yml`]: ../config/zulu_jre.yml +[Azul Zulu]: https://www.azul.com/products/zulu/ [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[jvmkill-mountainlion]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/mountainlion/x86_64/index.yml +[jvmkill-trusty]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/trusty/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[Zulu JRE]: jre-zulu_jre.md -[Azul Zulu]: https://www.azul.com/products/zulu/ [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering +[Volume Service]: https://docs.cloudfoundry.org/devguide/services/using-vol-services.html +[Zulu JRE]: jre-zulu_jre.md diff --git a/lib/java_buildpack/component/services.rb b/lib/java_buildpack/component/services.rb index af77a462fb..0953320eac 100644 --- a/lib/java_buildpack/component/services.rb +++ b/lib/java_buildpack/component/services.rb @@ -28,6 +28,15 @@ def initialize(raw) concat raw.values.flatten end + # Compares the name, label, and tags of each service to the given +filter+. The method returns the first service + # that the +filter+ matches. If no service matches, returns +nil+ + # + # @param [Regexp, String] filter a +RegExp+ or +String+ to match against the name, label, and tags of the services + # @return [Hash, nil] the first service that +filter+ matches. If no service matches, returns +nil+. + def find_service(filter) + find(&matcher(filter)) + end + # Compares the name, label, and tags of each service to the given +filter+. The method returns +true+ if the # +filter+ matches exactly one service, +false+ otherwise. # @@ -55,13 +64,29 @@ def one_service?(filter, *required_credentials) match end - # Compares the name, label, and tags of each service to the given +filter+. The method returns the first service - # that the +filter+ matches. If no service matches, returns +nil+ + # Compares the name, lavel,a nd tags of each service to the given +filter+. The method returns +true+ if the + # +filter+ matches exactly one volume service, +false+ otherwise. # # @param [Regexp, String] filter a +RegExp+ or +String+ to match against the name, label, and tags of the services - # @return [Hash, nil] the first service that +filter+ matches. If no service matches, returns +nil+. - def find_service(filter) - find(&matcher(filter)) + # @return [Boolean] +true+ if the +filter+ matches exactly one volume service with the required credentials, + # +false+ otherwise. + def one_volume_service?(filter) + candidates = select(&matcher(filter)) + + match = false + if candidates.one? + volume_mounts = candidates.first['volume_mounts'] + if !volume_mounts.nil? + match = volume_mounts.one? + else + logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger Services + logger.debug do + "A service with a name label or tag matching #{filter} was found, but was missing a volume_mount" + end + end + end + + match end private diff --git a/lib/java_buildpack/jre/jvmkill_agent.rb b/lib/java_buildpack/jre/jvmkill_agent.rb index 821c0e6aee..d435d55adf 100644 --- a/lib/java_buildpack/jre/jvmkill_agent.rb +++ b/lib/java_buildpack/jre/jvmkill_agent.rb @@ -31,11 +31,16 @@ def compile FileUtils.cp(file.path, jvmkill_agent) jvmkill_agent.chmod 0o755 end + + puts " Write terminal heap dumps to #{heap_dump_path}" if @application.services.one_volume_service? FILTER end # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.java_opts.add_agentpath_with_props(jvmkill_agent, 'printHeapHistogram' => '1') + properties = { 'printHeapHistogram' => '1' } + properties['heapDumpPath'] = heap_dump_path if @application.services.one_volume_service? FILTER + + @droplet.java_opts.add_agentpath_with_props(jvmkill_agent, properties) end protected @@ -47,10 +52,34 @@ def supports? private + FILTER = /heap-dump/ + + private_constant :FILTER + + def application_identifier + "#{@application.details['application_name']}-#{@application.details['application_id']}" + end + + def container_dir + @application.services.find_service(FILTER)['volume_mounts'].first['container_dir'] + end + + def heap_dump_path + "#{container_dir}/#{space_identifier}/#{application_identifier}/#{instance_identifier}.hprof" + end + + def instance_identifier + '$CF_INSTANCE_INDEX-%FT%T%z-$CF_INSTANCE_GUID' + end + def jvmkill_agent @droplet.sandbox + "bin/jvmkill-#{@version}" end + def space_identifier + "#{@application.details['space_name']}-#{@application.details['space_id']}" + end + end end diff --git a/spec/application_helper.rb b/spec/application_helper.rb index d3b320c7db..cf067d1f0a 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -48,7 +48,9 @@ let(:vcap_application) do { 'application_id' => 'test-application-id', 'application_name' => 'test-application-name', - 'application_version' => 'test-application-version' } + 'application_version' => 'test-application-version', + 'space_id' => 'test-space-id', + 'space_name' => 'test-space-name' } end let(:vcap_services) do diff --git a/spec/java_buildpack/component/services_spec.rb b/spec/java_buildpack/component/services_spec.rb index 7bf7926c3c..1f9d5e2fe0 100644 --- a/spec/java_buildpack/component/services_spec.rb +++ b/spec/java_buildpack/component/services_spec.rb @@ -72,6 +72,71 @@ expect(services.one_service?(/test-tag/, %w[foo bar])).not_to be end + it 'returns true from one_volume_service? if there is a matching name and no volume_mounts' do + expect(services.one_volume_service?('test-name')).not_to be + expect(services.one_volume_service?(/test-name/)).not_to be + end + + it 'returns true from one_volume_service? if there is a matching label and no volume_mounts' do + expect(services.one_volume_service?('test-label')).not_to be + expect(services.one_volume_service?(/test-label/)).not_to be + end + + it 'returns false from one_volume_service? if there is a matching tag and no volume_mounts' do + expect(services.one_volume_service?('test-tag')).not_to be + expect(services.one_volume_service?(/test-tag/)).not_to be + end + + context do + let(:service) do + { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + 'volume_mounts' => [] } + end + + it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do + expect(services.one_volume_service?('test-name')).not_to be + expect(services.one_volume_service?(/test-name/)).not_to be + end + + it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do + expect(services.one_volume_service?('test-label')).not_to be + expect(services.one_volume_service?(/test-label/)).not_to be + end + + it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do + expect(services.one_volume_service?('test-tag')).not_to be + expect(services.one_volume_service?(/test-tag/)).not_to be + end + + end + + context do + let(:service) do + { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', + 'device_type' => 'shared', + 'mode' => 'rw' }] } + end + + it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do + expect(services.one_volume_service?('test-name')).to be + expect(services.one_volume_service?(/test-name/)).to be + end + + it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do + expect(services.one_volume_service?('test-label')).to be + expect(services.one_volume_service?(/test-label/)).to be + end + + it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do + expect(services.one_volume_service?('test-tag')).to be + expect(services.one_volume_service?(/test-tag/)).to be + end + + end + it 'returns nil from find_service? if there is no service that matches' do expect(services.find_service('bad-test')).to be_nil expect(services.find_service(/bad-test/)).to be_nil diff --git a/spec/java_buildpack/jre/jvmkill_agent_spec.rb b/spec/java_buildpack/jre/jvmkill_agent_spec.rb index b2327f07cf..df87f10952 100644 --- a/spec/java_buildpack/jre/jvmkill_agent_spec.rb +++ b/spec/java_buildpack/jre/jvmkill_agent_spec.rb @@ -42,4 +42,17 @@ expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jvmkill_agent/bin/jvmkill-0.0.0=printHeapHistogram=1') end + it 'adds heap dump parameter to JAVA_OPTS when volume service available' do + allow(services).to receive(:one_volume_service?).with(/heap-dump/).and_return(true) + allow(services).to receive(:find_service).and_return('volume_mounts' => + [{ 'container_dir' => 'test-container-dir' }]) + + component.release + + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jvmkill_agent/bin/jvmkill-0.0.0=' \ + 'printHeapHistogram=1,heapDumpPath=test-container-dir/test-space-name-test-space-id/' \ + 'test-application-name-test-application-id/$CF_INSTANCE_INDEX-%FT%T%z-' \ + '$CF_INSTANCE_GUID.hprof') + end + end From 990b2305ac98f5596bf5e9bbfbf73ea608d35480 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 14 Jun 2017 15:56:54 -0700 Subject: [PATCH 295/812] Shorter Heap Dump IDs Previously the heapdump file location embedded the entire UUID for the space, the application, and the instance. This was, to put it mildly, long. This change shrinks that value to only include the first 8 characters (everything before the first hyphen) of those ids. --- lib/java_buildpack/jre/jvmkill_agent.rb | 6 +++--- spec/java_buildpack/jre/jvmkill_agent_spec.rb | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/jre/jvmkill_agent.rb b/lib/java_buildpack/jre/jvmkill_agent.rb index d435d55adf..33f15a789b 100644 --- a/lib/java_buildpack/jre/jvmkill_agent.rb +++ b/lib/java_buildpack/jre/jvmkill_agent.rb @@ -57,7 +57,7 @@ def supports? private_constant :FILTER def application_identifier - "#{@application.details['application_name']}-#{@application.details['application_id']}" + "#{@application.details['application_name']}-#{@application.details['application_id'][0...8]}" end def container_dir @@ -69,7 +69,7 @@ def heap_dump_path end def instance_identifier - '$CF_INSTANCE_INDEX-%FT%T%z-$CF_INSTANCE_GUID' + '$CF_INSTANCE_INDEX-%FT%T%z-${CF_INSTANCE_GUID:0:8}' end def jvmkill_agent @@ -77,7 +77,7 @@ def jvmkill_agent end def space_identifier - "#{@application.details['space_name']}-#{@application.details['space_id']}" + "#{@application.details['space_name']}-#{@application.details['space_id'][0...8]}" end end diff --git a/spec/java_buildpack/jre/jvmkill_agent_spec.rb b/spec/java_buildpack/jre/jvmkill_agent_spec.rb index df87f10952..7bd160c741 100644 --- a/spec/java_buildpack/jre/jvmkill_agent_spec.rb +++ b/spec/java_buildpack/jre/jvmkill_agent_spec.rb @@ -50,9 +50,9 @@ component.release expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jvmkill_agent/bin/jvmkill-0.0.0=' \ - 'printHeapHistogram=1,heapDumpPath=test-container-dir/test-space-name-test-space-id/' \ - 'test-application-name-test-application-id/$CF_INSTANCE_INDEX-%FT%T%z-' \ - '$CF_INSTANCE_GUID.hprof') + 'printHeapHistogram=1,heapDumpPath=test-container-dir/test-space-name-test-spa/' \ + 'test-application-name-test-app/$CF_INSTANCE_INDEX-%FT%T%z-' \ + '${CF_INSTANCE_GUID:0:8}.hprof') end end From 593251658cfdb68eb4351e4ec5e52ee75bfbcc9f Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 16 Jun 2017 12:26:04 -0700 Subject: [PATCH 296/812] Container Security Provider Documentation This change adds container security provider documentation. --- README.md | 1 + docs/framework-container_security_provider.md | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 docs/framework-container_security_provider.md diff --git a/README.md b/README.md index f758d280b9..eafc041432 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) + * [Container Security Provider](docs/framework-container_security_provider.md) ([Configuration](docs/framework-container_security_provider.md#configuration)) * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) * [Dyadic EKM Security Provider](docs/framework-dyadic_ekm_security_provider.md) ([Configuration](docs/framework-dyadic_ekm_security_provider.md#configuration)) * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) diff --git a/docs/framework-container_security_provider.md b/docs/framework-container_security_provider.md new file mode 100644 index 0000000000..2d5cab51ed --- /dev/null +++ b/docs/framework-container_security_provider.md @@ -0,0 +1,37 @@ +# Container Security Provider +The Container Security Provider Framework adds a Security Provider to the JVM that automatically includes BOSH trusted certificates and Diego identity certificates and private keys. + + + + + + + + + + +
Detection CriterionUnconditional
Tagscontainer-security-provider=<version>
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/container_security_provider.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Container Customizer repository index ([details][repositories]). +| `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. + +## Security Provider +The [security provider][] added by this framework contributes two types, a `TrustManagerFactory` and a `KeyManagerFactory`. The `TrustManagerFactory` adds an additional new `TrustManager` after the configured system `TrustManager` which reads the contents of `/etc/ssl/certs/ca-certificates.crt` which is where [BOSH trusted certificates][] are placed. The `KeyManagerFactory` adds an additional `KeyManager` after the configured system `KeyManager` which reads the contents of the files specified by `$CF_INSTANCE_CERT` and `$CF_INSTANCE_KEY` which are set by Diego to give each container a unique cryptographic identity. These `TrustManager`s and `KeyManager`s are used transparently by any networking library that reads standard system SSL configuration and can be used to enable system-wide trust and [mutual TLS authentication][]. + + +[`config/container_security_provider.yml`]: ../config/container_security_provider.yml +[BOSH trusted certificates]: https://bosh.io/docs/trusted-certs.html +[Configuration and Extension]: ../README.md#configuration-and-extension +[mutual TLS authentication]: https://en.wikipedia.org/wiki/Mutual_authentication +[repositories]: extending-repositories.md +[security provider]: https://github.com/cloudfoundry/java-buildpack-security-provider +[this listing]: http://download.pivotal.io.s3.amazonaws.com/container-security-provider/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering From 4a78d5d748547b3d2c1ddfa108cb052d4213fe67 Mon Sep 17 00:00:00 2001 From: Donnie Propst Date: Fri, 9 Jun 2017 17:29:58 -0400 Subject: [PATCH 297/812] Contrast Security Framework This change adds the Contrast Security Framework which detects a service with name/label/tag of contrast-security. [#446] --- README.md | 1 + config/components.yml | 1 + config/contrast_security_agent.yml | 19 +++ docs/framework-contrast_security_agent.md | 41 +++++++ .../framework/contrast_security_agent.rb | 112 ++++++++++++++++++ .../fixtures/stub-contrast-security-agent.jar | 0 .../framework/contrast_security_agent_spec.rb | 71 +++++++++++ 7 files changed, 245 insertions(+) create mode 100644 config/contrast_security_agent.yml create mode 100644 docs/framework-contrast_security_agent.md create mode 100644 lib/java_buildpack/framework/contrast_security_agent.rb create mode 100644 spec/fixtures/stub-contrast-security-agent.jar create mode 100644 spec/java_buildpack/framework/contrast_security_agent_spec.rb diff --git a/README.md b/README.md index dbb6f4a70a..b14328e54c 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) + * [Contrast Security Agent](docs/framework-contrast_security_agent.md) ([Configuration](docs/framework-contrast_security_agent.md#configuration)) * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) * [Dyadic EKM Security Provider](docs/framework-dyadic_ekm_security_provider.md) ([Configuration](docs/framework-dyadic_ekm_security_provider.md#configuration)) * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 21f45ab93c..9946742056 100644 --- a/config/components.yml +++ b/config/components.yml @@ -40,6 +40,7 @@ frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::ContainerSecurityProvider" + - "JavaBuildpack::Framework::ContrastSecurityAgent" - "JavaBuildpack::Framework::Debug" - "JavaBuildpack::Framework::DyadicEkmSecurityProvider" - "JavaBuildpack::Framework::DynatraceAppmonAgent" diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml new file mode 100644 index 0000000000..855aff80eb --- /dev/null +++ b/config/contrast_security_agent.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the ContrastSecurity framework +--- +version: 3.+ +repository_root: "https://artifacts.contrastsecurity.com/agents/java/" diff --git a/docs/framework-contrast_security_agent.md b/docs/framework-contrast_security_agent.md new file mode 100644 index 0000000000..f4e19732ef --- /dev/null +++ b/docs/framework-contrast_security_agent.md @@ -0,0 +1,41 @@ +# Contrast Security Agent Framework +The Contrast Security Agent Framework causes an application to be automatically configured to work with a bound [Contrast Security Service][]. + + + + + +
Detection CriterionExistence of a single bound Contrast Security service. The existence of an Contrast Security service defined by the VCAP_SERVICES payload containing a service name, label or tag with contrast-security as a substring. +
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +When binding ContrastSecurity using a user-provided service, it must have name or tag with `contrast-security` in it. The credential payload can contain the following entries: + +| Name | Description +| ---- | ----------- +| `teamserver_url` | The base URL in which your user has access to and the URL to which the Agent will report. ex: https://app.contrastsecurity.com +| `username` | The account name to use when downloading the agent +| `org_uuid` | The org uuid to send app information to, this is the org that your bound application will appear within +| `api_key` | Your user's api key +| `service_key` | Your user's service key + + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/contrast_security_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Contrast Security repository index ([details][repositories]). +| `version` | The version of Contrast Security to use. Candidate versions can be found in [this listing][]. + +[Contrast Security]: https://www.contrastsecurity.com +[Configuration and Extension]: ../README.md#configuration-and-extension +[Contrast Security Service]: https://www.contrastsecurity.com +[`config/contrast_security_agent.yml`]: ../config/contrast_security_agent.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[repositories]: extending-repositories.md +[this listing]: https://artifacts.contrastsecurity.com/agents/java/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb new file mode 100644 index 0000000000..164bcaebb6 --- /dev/null +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -0,0 +1,112 @@ +# Encoding: utf-8 + +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'rexml/document' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for running the Contrast Security Agent support. + class ContrastSecurityAgent < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar(boot_class_name) + build_contrast_configuration + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + app_name = @application.details['application_name'] || 'ROOT' + java_opts = @droplet.java_opts + java_opts.add_system_property('contrast.dir', '$TMPDIR') + java_opts.add_system_property('contrast.override.appname', app_name) + path = java_opts.qualify_path(@droplet.sandbox) + java_opts.add_preformatted_options("-javaagent:#{path}/#{boot_class_name}=#{path}/contrast.config") + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service?(CONTRAST_FILTER, TEAMSERVER_URL, USERNAME, API_KEY, SERVICE_KEY) + end + + private + + API_KEY = 'api_key'.freeze + CONTRAST_FILTER = 'contrast-security'.freeze + SERVICE_KEY = 'service_key'.freeze + TEAMSERVER_URL = 'teamserver_url'.freeze + USERNAME = 'username'.freeze + + private_constant :API_KEY + private_constant :CONTRAST_FILTER + private_constant :SERVICE_KEY + private_constant :TEAMSERVER_URL + private_constant :USERNAME + + PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins.'.freeze + + def credentials + @application.services.find_service(CONTRAST_FILTER)['credentials'] + end + + def boot_class_name + version = @version.to_s.split('_')[0] + "contrast-engine-#{version}.jar" + end + + def build_contrast_configuration + doc = REXML::Document.new + contrast = doc.add_element('contrast') + (contrast.add_element 'id').add_text('default') + (contrast.add_element 'global-key').add_text(credentials[API_KEY]) + user = contrast.add_element('user') + (user.add_element 'id').add_text(credentials[USERNAME]) + (user.add_element 'key').add_text(credentials[SERVICE_KEY]) + (contrast.add_element 'url').add_text("#{credentials[TEAMSERVER_URL]}/Contrast/s/") + (contrast.add_element 'results-mode').add_text('never') + + add_plugins(contrast) + + contrast_config.open(File::CREAT | File::WRONLY) { |f| f.write(doc) } + end + + def add_plugins(config) + plugin_package = 'com.aspectsecurity.contrast.runtime.agent.plugins.' + plugin_group = config.add_element('plugins') + (plugin_group.add_element 'plugin').add_text("#{plugin_package}.security.SecurityPlugin") + (plugin_group.add_element 'plugin').add_text("#{plugin_package}.architecture.ArchitecturePlugin") + (plugin_group.add_element 'plugin').add_text("#{plugin_package}.appupdater.ApplicationUpdatePlugin") + (plugin_group.add_element 'plugin').add_text("#{plugin_package}.sitemap.SitemapPlugin") + (plugin_group.add_element 'plugin').add_text("#{plugin_package}.frameworks.FrameworkSupportPlugin") + (plugin_group.add_element 'plugin').add_text("#{plugin_package}.http.HttpPlugin") + end + + def contrast_config + @droplet.sandbox + 'contrast.config' + end + + end + + end +end \ No newline at end of file diff --git a/spec/fixtures/stub-contrast-security-agent.jar b/spec/fixtures/stub-contrast-security-agent.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb new file mode 100644 index 0000000000..6b182d48c5 --- /dev/null +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -0,0 +1,71 @@ +# Encoding: utf-8 + +# Cloud Foundry Java Buildpack +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/contrast_security_agent' +require 'java_buildpack/util/tokenized_version' + +describe JavaBuildpack::Framework::ContrastSecurityAgent do + include_context 'component_helper' + let(:configuration) do + { 'teamserver_url' => 'a_url', + 'org_uuid' => '12345', + 'username' => 'contrast_user', + 'api_key' => 'api_test', + 'service_key' => 'service_test' } + end + + it 'does not detect without contrastsecurity service' do + expect(component.detect).to be_nil + end + + context do + before do + allow(services).to receive(:one_service?).with(/contrast[-]?security/, + 'teamserver_url','username', 'api_key', 'service_key').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => :configuration) + end + + it 'detects with contrastsecurity service' do + expect(component.detect).to eq("contrast-security-agent=#{version}") + end + + it 'downloads Contrast Security agent JAR', + cache_fixture: 'stub-contrast-security-agent.jar' do + + component.compile + expect(sandbox + 'contrast-engine-0.0.0.jar').to exist + end + + it 'updates JAVA_OPTS' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/contrast_security_agent/contrast-engine-0.0.0.jar'\ + '=$PWD/.java-buildpack/contrast_security_agent/contrast.config') + expect(java_opts).to include('-Dcontrast.dir=$TMPDIR') + expect(java_opts).to include('-Dcontrast.override.appname=test-application-name') + end + + it 'created contrast.config', + cache_fixture: 'stub-contrast-security-agent.jar' do + component.compile + expect(sandbox + 'contrast.config').to exist + end + end + +end From 01ebbb5539a6d412dc9766c79db7642c23aeb867 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 19 Jun 2017 09:17:48 -0700 Subject: [PATCH 298/812] Polishing This change does some final polishing of the Contrast Security Framework. [resolves #446] --- .idea/dictionaries/bhale.xml | 3 + ...ons__JSON_.xml => versions__Markdown_.xml} | 4 +- .../versions__Pivotal_Network_.xml | 25 +++++ docs/framework-contrast_security_agent.md | 6 +- .../framework/contrast_security_agent.rb | 94 +++++++++++-------- rakelib/versions_task.rb | 1 + .../framework/contrast_security_agent_spec.rb | 22 ++--- 7 files changed, 97 insertions(+), 58 deletions(-) rename .idea/runConfigurations/{versions__JSON_.xml => versions__Markdown_.xml} (90%) create mode 100644 .idea/runConfigurations/versions__Pivotal_Network_.xml diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index dd635b2f2a..7af11507f1 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -6,6 +6,7 @@ appdynamics applicationid argv + aspectsecurity atpack bootclasspath buildpack @@ -22,6 +23,7 @@ dirname distapplication dnewrelic + dotmatch enterprisemanager etag extname @@ -98,6 +100,7 @@ stubjre submodules tasklib + teamserver tenanttoken tmpdir tokenized diff --git a/.idea/runConfigurations/versions__JSON_.xml b/.idea/runConfigurations/versions__Markdown_.xml similarity index 90% rename from .idea/runConfigurations/versions__JSON_.xml rename to .idea/runConfigurations/versions__Markdown_.xml index 1d3402880a..45b443aeaf 100644 --- a/.idea/runConfigurations/versions__JSON_.xml +++ b/.idea/runConfigurations/versions__Markdown_.xml @@ -1,5 +1,5 @@ - + @@ -14,7 +14,7 @@ - + diff --git a/.idea/runConfigurations/versions__Pivotal_Network_.xml b/.idea/runConfigurations/versions__Pivotal_Network_.xml new file mode 100644 index 0000000000..6b946e443b --- /dev/null +++ b/.idea/runConfigurations/versions__Pivotal_Network_.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/framework-contrast_security_agent.md b/docs/framework-contrast_security_agent.md index f4e19732ef..ab6e5d4ea0 100644 --- a/docs/framework-contrast_security_agent.md +++ b/docs/framework-contrast_security_agent.md @@ -14,12 +14,10 @@ When binding ContrastSecurity using a user-provided service, it must have name o | Name | Description | ---- | ----------- -| `teamserver_url` | The base URL in which your user has access to and the URL to which the Agent will report. ex: https://app.contrastsecurity.com -| `username` | The account name to use when downloading the agent -| `org_uuid` | The org uuid to send app information to, this is the org that your bound application will appear within | `api_key` | Your user's api key | `service_key` | Your user's service key - +| `teamserver_url` | The base URL in which your user has access to and the URL to which the Agent will report. ex: https://app.contrastsecurity.com +| `username` | The account name to use when downloading the agent ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index 164bcaebb6..812490fbcc 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -18,6 +18,7 @@ require 'fileutils' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' +require 'java_buildpack/util/qualify_path' require 'rexml/document' module JavaBuildpack @@ -25,88 +26,99 @@ module Framework # Encapsulates the functionality for running the Contrast Security Agent support. class ContrastSecurityAgent < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_jar(boot_class_name) - build_contrast_configuration + download_jar @droplet.copy_resources + + write_configuration @application.services.find_service(CONTRAST_FILTER)['credentials'] end # (see JavaBuildpack::Component::BaseComponent#release) def release - app_name = @application.details['application_name'] || 'ROOT' - java_opts = @droplet.java_opts - java_opts.add_system_property('contrast.dir', '$TMPDIR') - java_opts.add_system_property('contrast.override.appname', app_name) - path = java_opts.qualify_path(@droplet.sandbox) - java_opts.add_preformatted_options("-javaagent:#{path}/#{boot_class_name}=#{path}/contrast.config") + @droplet.java_opts + .add_system_property('contrast.dir', '$TMPDIR') + .add_system_property('contrast.override.appname', application_name) + .add_preformatted_options("-javaagent:#{qualify_path(@droplet.sandbox + jar_name, @droplet.root)}=" \ + "#{qualify_path(contrast_config, @droplet.root)}") end protected + # (see JavaBuildpack::Component::VersionedDependencyComponent#jar_name) + def jar_name + "contrast-engine-#{@version.to_s.split('_')[0]}.jar" + end + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service?(CONTRAST_FILTER, TEAMSERVER_URL, USERNAME, API_KEY, SERVICE_KEY) + @application.services.one_service?(CONTRAST_FILTER, API_KEY, SERVICE_KEY, TEAMSERVER_URL, USERNAME) end private API_KEY = 'api_key'.freeze + CONTRAST_FILTER = 'contrast-security'.freeze + + PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins.'.freeze + SERVICE_KEY = 'service_key'.freeze + TEAMSERVER_URL = 'teamserver_url'.freeze + USERNAME = 'username'.freeze - private_constant :API_KEY - private_constant :CONTRAST_FILTER - private_constant :SERVICE_KEY - private_constant :TEAMSERVER_URL - private_constant :USERNAME + private_constant :API_KEY, :CONTRAST_FILTER, :PLUGIN_PACKAGE, :SERVICE_KEY, :TEAMSERVER_URL, :USERNAME - PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins.'.freeze + def add_contrast(doc, credentials) + contrast = doc.add_element('contrast') + (contrast.add_element 'id').add_text('default') + (contrast.add_element 'global-key').add_text(credentials[API_KEY]) + (contrast.add_element 'url').add_text("#{credentials[TEAMSERVER_URL]}/Contrast/s/") + (contrast.add_element 'results-mode').add_text('never') - def credentials - @application.services.find_service(CONTRAST_FILTER)['credentials'] + add_user contrast, credentials + add_plugins contrast end - def boot_class_name - version = @version.to_s.split('_')[0] - "contrast-engine-#{version}.jar" + def add_plugins(contrast) + plugin_group = contrast.add_element('plugins') + + (plugin_group.add_element 'plugin').add_text("#{PLUGIN_PACKAGE}.security.SecurityPlugin") + (plugin_group.add_element 'plugin').add_text("#{PLUGIN_PACKAGE}.architecture.ArchitecturePlugin") + (plugin_group.add_element 'plugin').add_text("#{PLUGIN_PACKAGE}.appupdater.ApplicationUpdatePlugin") + (plugin_group.add_element 'plugin').add_text("#{PLUGIN_PACKAGE}.sitemap.SitemapPlugin") + (plugin_group.add_element 'plugin').add_text("#{PLUGIN_PACKAGE}.frameworks.FrameworkSupportPlugin") + (plugin_group.add_element 'plugin').add_text("#{PLUGIN_PACKAGE}.http.HttpPlugin") end - def build_contrast_configuration - doc = REXML::Document.new - contrast = doc.add_element('contrast') - (contrast.add_element 'id').add_text('default') - (contrast.add_element 'global-key').add_text(credentials[API_KEY]) + def add_user(contrast, credentials) user = contrast.add_element('user') (user.add_element 'id').add_text(credentials[USERNAME]) (user.add_element 'key').add_text(credentials[SERVICE_KEY]) - (contrast.add_element 'url').add_text("#{credentials[TEAMSERVER_URL]}/Contrast/s/") - (contrast.add_element 'results-mode').add_text('never') - - add_plugins(contrast) - - contrast_config.open(File::CREAT | File::WRONLY) { |f| f.write(doc) } end - def add_plugins(config) - plugin_package = 'com.aspectsecurity.contrast.runtime.agent.plugins.' - plugin_group = config.add_element('plugins') - (plugin_group.add_element 'plugin').add_text("#{plugin_package}.security.SecurityPlugin") - (plugin_group.add_element 'plugin').add_text("#{plugin_package}.architecture.ArchitecturePlugin") - (plugin_group.add_element 'plugin').add_text("#{plugin_package}.appupdater.ApplicationUpdatePlugin") - (plugin_group.add_element 'plugin').add_text("#{plugin_package}.sitemap.SitemapPlugin") - (plugin_group.add_element 'plugin').add_text("#{plugin_package}.frameworks.FrameworkSupportPlugin") - (plugin_group.add_element 'plugin').add_text("#{plugin_package}.http.HttpPlugin") + def application_name + @application.details['application_name'] || 'ROOT' end def contrast_config @droplet.sandbox + 'contrast.config' end + def write_configuration(credentials) + doc = REXML::Document.new + + add_contrast doc, credentials + + contrast_config.open(File::CREAT | File::WRONLY) { |f| f.write(doc) } + end + end end -end \ No newline at end of file + +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 436e8b6f81..fe1baebd6e 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -52,6 +52,7 @@ def initialize 'app_dynamics_agent' => 'AppDynamics Agent', 'container_customizer' => 'Spring Boot Container Customizer', 'container_security_provider' => 'Container Security Provider', + 'contrast_security_agent' => 'Contrast Security Agent', 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', 'dynatrace_one_agent' => 'Dynatrace OneAgent', diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb index 6b182d48c5..3319b1f2bb 100644 --- a/spec/java_buildpack/framework/contrast_security_agent_spec.rb +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -22,23 +22,21 @@ describe JavaBuildpack::Framework::ContrastSecurityAgent do include_context 'component_helper' - let(:configuration) do - { 'teamserver_url' => 'a_url', - 'org_uuid' => '12345', - 'username' => 'contrast_user', - 'api_key' => 'api_test', - 'service_key' => 'service_test' } - end it 'does not detect without contrastsecurity service' do expect(component.detect).to be_nil end context do + before do - allow(services).to receive(:one_service?).with(/contrast[-]?security/, - 'teamserver_url','username', 'api_key', 'service_key').and_return(true) - allow(services).to receive(:find_service).and_return('credentials' => :configuration) + allow(services).to receive(:one_service?).with(/contrast-security/, 'api_key', 'service_key', 'teamserver_url', + 'username').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'teamserver_url' => 'a_url', + 'org_uuid' => '12345', + 'username' => 'contrast_user', + 'api_key' => 'api_test', + 'service_key' => 'service_test' }) end it 'detects with contrastsecurity service' do @@ -55,7 +53,7 @@ it 'updates JAVA_OPTS' do component.release - expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/contrast_security_agent/contrast-engine-0.0.0.jar'\ + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/contrast_security_agent/contrast-engine-0.0.0.jar' \ '=$PWD/.java-buildpack/contrast_security_agent/contrast.config') expect(java_opts).to include('-Dcontrast.dir=$TMPDIR') expect(java_opts).to include('-Dcontrast.override.appname=test-application-name') @@ -63,9 +61,11 @@ it 'created contrast.config', cache_fixture: 'stub-contrast-security-agent.jar' do + component.compile expect(sandbox + 'contrast.config').to exist end + end end From 45d7b15436ddf800d873865e8df6b0e89cdf351c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 20 Jun 2017 09:41:36 -0700 Subject: [PATCH 299/812] Security Provider Positions After consultation with some of the HSM providers, my plan to place the HSM security providers earlier in the hierarchy seems flawed. This change moves them back to the last entry in the hierarchy. --- lib/java_buildpack/framework/dyadic_ekm_security_provider.rb | 2 +- lib/java_buildpack/framework/luna_security_provider.rb | 2 +- lib/java_buildpack/framework/protect_app_security_provider.rb | 2 +- .../framework/container_security_provider_spec.rb | 2 +- .../framework/dyadic_ekm_security_provider_spec.rb | 2 +- spec/java_buildpack/framework/luna_security_provider_spec.rb | 2 +- .../framework/protect_app_security_provider_spec.rb | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index 97f0d48d19..ddb8f5fc2c 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -31,7 +31,7 @@ def compile setup_ext_dir @droplet.copy_resources - @droplet.security_providers.insert 2, 'com.dyadicsec.provider.DYCryptoProvider' + @droplet.security_providers << 'com.dyadicsec.provider.DYCryptoProvider' credentials = @application.services.find_service(FILTER)['credentials'] write_key credentials['key'] diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index f62506190e..1c18e97a2f 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -31,7 +31,7 @@ def compile setup_ext_dir @droplet.copy_resources - @droplet.security_providers.insert 2, 'com.safenetinc.luna.provider.LunaProvider' + @droplet.security_providers << 'com.safenetinc.luna.provider.LunaProvider' credentials = @application.services.find_service(FILTER)['credentials'] write_client credentials['client'] diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb index 4bb1d8dcc4..da1af66ba8 100644 --- a/lib/java_buildpack/framework/protect_app_security_provider.rb +++ b/lib/java_buildpack/framework/protect_app_security_provider.rb @@ -32,7 +32,7 @@ def compile download_zip false @droplet.copy_resources - @droplet.security_providers.insert 2, 'com.ingrian.security.nae.IngrianProvider' + @droplet.security_providers << 'com.ingrian.security.nae.IngrianProvider' credentials = @application.services.find_service(FILTER)['credentials'] diff --git a/spec/java_buildpack/framework/container_security_provider_spec.rb b/spec/java_buildpack/framework/container_security_provider_spec.rb index 81b0f6322b..cfd7f46e3a 100644 --- a/spec/java_buildpack/framework/container_security_provider_spec.rb +++ b/spec/java_buildpack/framework/container_security_provider_spec.rb @@ -34,7 +34,7 @@ cache_fixture: 'stub-container-security-provider.jar' do component.compile - expect(security_providers).to include('org.cloudfoundry.security.CloudFoundryContainerProvider') + expect(security_providers[1]).to eq('org.cloudfoundry.security.CloudFoundryContainerProvider') end end diff --git a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb index 428a0d56e0..a0e0ff4e9e 100644 --- a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb +++ b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb @@ -91,7 +91,7 @@ component.compile - expect(security_providers).to include('com.dyadicsec.provider.DYCryptoProvider') + expect(security_providers.last).to eq('com.dyadicsec.provider.DYCryptoProvider') end it 'adds extension directory' do diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index 1e710b1c6e..54080cf3c0 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -115,7 +115,7 @@ cache_fixture: 'stub-luna-security-provider.tar' do component.compile - expect(security_providers).to include('com.safenetinc.luna.provider.LunaProvider') + expect(security_providers.last).to eq('com.safenetinc.luna.provider.LunaProvider') end it 'adds extension directory' do diff --git a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb index 3fb7d27173..345866405d 100644 --- a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb +++ b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb @@ -74,7 +74,7 @@ component.compile - expect(security_providers).to include('com.ingrian.security.nae.IngrianProvider') + expect(security_providers.last).to eq('com.ingrian.security.nae.IngrianProvider') end it 'copies resources', From 5bf6497a53b1ba11aa2ee4b60a311c0627ecfe71 Mon Sep 17 00:00:00 2001 From: Bharath Appali Date: Fri, 19 May 2017 15:31:54 +0530 Subject: [PATCH 300/812] IBM JRE This change adds the IBM JRE to the collection of available JREs in the buildpack. [#427] --- README.md | 1 + config/components.yml | 1 + config/ibm_jre.yml | 25 ++ docs/jre-ibm_jre.md | 59 +++++ lib/java_buildpack/jre/ibm_jre.rb | 53 +++++ lib/java_buildpack/jre/ibm_jre_initializer.rb | 213 ++++++++++++++++++ spec/fixtures/stub-download.bin | 0 spec/fixtures/stub-java.bin | 0 .../jre/ibm_jre_initializer_spec.rb | 64 ++++++ spec/java_buildpack/jre/ibm_jre_spec.rb | 70 ++++++ 10 files changed, 486 insertions(+) create mode 100644 config/ibm_jre.yml create mode 100644 docs/jre-ibm_jre.md create mode 100644 lib/java_buildpack/jre/ibm_jre.rb create mode 100644 lib/java_buildpack/jre/ibm_jre_initializer.rb create mode 100644 spec/fixtures/stub-download.bin create mode 100644 spec/fixtures/stub-java.bin create mode 100644 spec/java_buildpack/jre/ibm_jre_initializer_spec.rb create mode 100644 spec/java_buildpack/jre/ibm_jre_spec.rb diff --git a/README.md b/README.md index b14328e54c..3ee7876ca1 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) * [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration)) * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) + * [IBM® SDK, Java™ Technology Edition](docs/jre-ibm_jre.md) ([Configuration](docs/jre-ibm_jre.md#configuration)) * [Extending](docs/extending.md) * [Application](docs/extending-application.md) * [Droplet](docs/extending-droplet.md) diff --git a/config/components.yml b/config/components.yml index 9946742056..773ce228b7 100644 --- a/config/components.yml +++ b/config/components.yml @@ -29,6 +29,7 @@ containers: # In order to use Zulu JREs instead of OpenJDK, you must comment out the OpenJDK line and uncomment the Zulu line. # Please see the documentation for more detail. jres: +# - "JavaBuildpack::Jre::IbmJRE" - "JavaBuildpack::Jre::OpenJdkJRE" # - "JavaBuildpack::Jre::OracleJRE" # - "JavaBuildpack::Jre::ZuluJRE" diff --git a/config/ibm_jre.yml b/config/ibm_jre.yml new file mode 100644 index 0000000000..f6659f7f7d --- /dev/null +++ b/config/ibm_jre.yml @@ -0,0 +1,25 @@ +# Cloud Foundry Java Buildpack +# Copyright 2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Configuration for JRE repository +--- +jre: + version: 1.8.+ + repository_root: "https://raw.githubusercontent.com/ibmruntimes/ci.docker/master/ibmjava/meta/jre/linux/x86_64/" + heap_ratio: 0.75 +jvmkill_agent: + version: 1.+ + repository_root: "https://raw.githubusercontent.com/ibmruntimes/jvmkill/jvmkill-ibmagent/jvmkill-agent/" diff --git a/docs/jre-ibm_jre.md b/docs/jre-ibm_jre.md new file mode 100644 index 0000000000..8660c4b9b8 --- /dev/null +++ b/docs/jre-ibm_jre.md @@ -0,0 +1,59 @@ +## IBM JRE +IBM JRE provides IBM® SDK, Java™ Technology Edition, Version 8. Unless otherwise configured, the version of Java that will be used is specified in [`config/ibm_jre.yml`][]. See the license section for restrictions that relate to the use of this image. For more information about IBM® SDK, Java™ Technology Edition and API documentation, see the [IBM Knowledge Center][]. + +### License +Licenses for the products installed within the buildpack: + +IBM® SDK, Java™ Technology Edition, Version 8: [International License Agreement for Non-Warranted Programs][]. + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The JRE can be configured by modifying the [`config/ibm_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so, it supports the [version syntax][] defined there. + +To use IBM JRE instead of OpenJDK without forking java-buildpack, set environment variable: + +`cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::IbmJRE"]}'` + +`cf restage ` + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the IBM JRE repository index ([details][repositories]). +| `version` | The version of Java runtime to use. + +### TLS Options +It is recommended to use the following Transport Layer Security (TLS) options for IBM JRE version 8 and above: + +`cf set-env JAVA_OPTS '-Dcom.ibm.jsse2.overrideDefaultTLS=true'` + +### Additional Resources +The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/ibm_jre` directory in the buildpack fork. + +#### Custom CA Certificates +To add custom SSL certificates, add your `cacerts` file to `resources/ibm_jre/jre/lib/security/cacerts`. This file will be overlayed onto the IBM JRE distribution. + +### Memory +The total available memory for the application's container is specified when an application is pushed.The Java buildpack uses this value to control the JRE's use of various regions of memory and logs the JRE memory settings when the application starts or restarts. + +Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. + +#### Total Memory +The user can change the container's total memory available to influence the JRE memory settings. Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory available results in the heap size setting increasing or decreasing by a corresponding amount. + +#### Memory Calculation +The user can configure the desired heap ratio (`-Xmx`) by changing the `heap_ratio` attribute under `jre` in [`config/ibm_jre.yml`][] and the buildpack calculates the `-Xmx Memory Setting` based on the total memory available. + +The container's total memory is logged during `cf push` and `cf scale`, for example: +``` + state since cpu memory disk details +#0 running 2017-04-10 02:20:03 PM 0.0% 896K of 1G 1.3M of 1G +``` + +[`config/components.yml`]: ../config/components.yml +[`config/ibm_jre.yml`]: ../config/ibm_jre.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering +[IBM Knowledge Center]: http://www.ibm.com/support/knowledgecenter/SSYKE2/welcome_javasdk_family.html +[International License Agreement for Non-Warranted Programs]: http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=&li_formnum=L-PMAA-A3Z8P2&title=IBM%AE+SDK%2C+Java%99+Technology+Edition%2C+Version+8.0&l=en diff --git a/lib/java_buildpack/jre/ibm_jre.rb b/lib/java_buildpack/jre/ibm_jre.rb new file mode 100644 index 0000000000..a7404c71a4 --- /dev/null +++ b/lib/java_buildpack/jre/ibm_jre.rb @@ -0,0 +1,53 @@ +# Cloud Foundry Java Buildpack +# Copyright 2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/modular_component' +require 'java_buildpack/jre' +require 'java_buildpack/jre/ibm_jre_initializer' +require 'java_buildpack/jre/jvmkill_agent' +require 'java_buildpack/jre/open_jdk_like_security_providers' + +module JavaBuildpack + module Jre + + # Encapsulates the detect, compile, and release functionality for selecting a JRE. + class IbmJRE < JavaBuildpack::Component::ModularComponent + + protected + + # (see JavaBuildpack::Component::ModularComponent#command) + def command + # no command need to be executed + end + + # (see JavaBuildpack::Component::ModularComponent#sub_components) + def sub_components(context) + [ + IbmJreInitializer.new(sub_configuration_context(context, 'jre') + .merge(component_name: self.class.to_s.space_case)), + JvmkillAgent.new(sub_configuration_context(context, 'jvmkill_agent')), + OpenJDKLikeSecurityProviders.new(context) + ] + end + + # (see JavaBuildpack::Component::ModularComponent#supports?) + def supports? + true + end + + end + + end +end diff --git a/lib/java_buildpack/jre/ibm_jre_initializer.rb b/lib/java_buildpack/jre/ibm_jre_initializer.rb new file mode 100644 index 0000000000..4cecee65c9 --- /dev/null +++ b/lib/java_buildpack/jre/ibm_jre_initializer.rb @@ -0,0 +1,213 @@ +# Cloud Foundry Java Buildpack +# Copyright 2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'digest' +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/jre' +require 'java_buildpack/util/tokenized_version' + +module JavaBuildpack + module Jre + + # Encapsulates the detect, compile, and release functionality for selecting a JRE. + class IbmJreInitializer < JavaBuildpack::Component::VersionedDependencyComponent + + # Creates an instance + # + # @param [Hash] context a collection of utilities used the component + def initialize(context) + @application = context[:application] + @component_name = context[:component_name] + @configuration = context[:configuration] + @droplet = context[:droplet] + + @droplet.java_home.root = @droplet.sandbox + 'jre/' + end + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + @version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, + @configuration) + @droplet.java_home.version = @version + super + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download(@version, @uri, @component_name) do |file| + with_timing "Installing #{@component_name} to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do + install_bin(@droplet.sandbox, file) + end + end + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet + .java_opts + .add_system_property('java.io.tmpdir', '$TMPDIR') + @droplet.java_opts << '-Xtune:virtualized' + @droplet.java_opts.concat mem_opts + @droplet.java_opts << '-Xshareclasses:none' + end + + private + + # constant HEAP_RATIO is the ratio of memory assigned to the heap + # as against the container total and is set using -Xmx. + HEAP_RATIO = 0.75 + + KILO = 1024 + + private_constant :HEAP_RATIO, :KILO + + # Installs the Downloaded InstallAnywhere (tm) BIN file to the target directory + # + # @param [String] target_directory, Where the java needs to be installed + # @param [File] file, InstallAnywhere (tm) BIN file + # @return [Void] + def install_bin(target_directory, file) + FileUtils.mkdir_p target_directory + response_file = Tempfile.new('response.properties') + response_file.puts('INSTALLER_UI=silent') + response_file.puts('LICENSE_ACCEPTED=TRUE') + response_file.puts("USER_INSTALL_DIR=#{target_directory}") + response_file.close + + File.chmod(0o755, file.path) unless File.executable?(file.path) + shell "#{file.path} -i silent -f #{response_file.path} 2>&1" + end + + # Returns the max heap size ('-Xmx') value + def mem_opts + mopts = [] + total_memory = memory_limit_finder + if total_memory.nil? + # if no memory option has been set by cloudfoundry, we just assume defaults + else + calculated_heap_ratio = heap_ratio_verification(heap_ratio) + heap_size = heap_size_calculator(total_memory, calculated_heap_ratio) + mopts.push "-Xmx#{heap_size}" + end + mopts + end + + # Returns the heap_ratio attribute in config file (if specified) or the HEAP_RATIO constant value + def heap_ratio + @configuration['heap_ratio'] || HEAP_RATIO + end + + # Returns the container total memory limit in bytes + def memory_limit_finder + memory_limit = ENV['MEMORY_LIMIT'] + return nil unless memory_limit + memory_limit_size = memory_size_bytes(memory_limit) + raise "Invalid negative $MEMORY_LIMIT #{memory_limit}" if memory_limit_size < 0 + memory_limit_size + end + + # Returns the no. of bytes for a given string of minified size representation + # + # @param [String] size, A minified memory representation string + # @return [Integer] bytes, value of size in bytes + def memory_size_bytes(size) + if size == '0' + bytes = 0 + else + raise "Invalid memory size '#{size}'" if !size || size.length < 2 + unit = size[-1] + value = size[0..-2] + raise "Invalid memory size '#{size}'" unless check_is_integer? value + value = size.to_i + # store the bytes + bytes = calculate_bytes(unit, value) + end + bytes + end + + # Returns the no. of bytes for a given memory size unit + # + # @param [String] unit, Represents a Memory Size Unit + # @param [Integer] value + # @return [Integer] bytes, value of size in bytes + def calculate_bytes(unit, value) + if %w[b B].include?(unit) + bytes = value + elsif %w[k K].include?(unit) + bytes = KILO * value + elsif %w[m M].include?(unit) + bytes = KILO * KILO * value + elsif %w[g G].include?(unit) + bytes = KILO * KILO * KILO * value + else + raise "Invalid unit '#{unit}' in memory size" + end + bytes + end + + # Checks whether the given value is an Integer + # + # @param [String] v, value as a string + def check_is_integer?(v) + v = Float(v) + v && v.floor == v + end + + # Calculates the Heap size as per the Heap ratio + # + # @param [Integer] membytes, total memory in bytes + # @param [Numeric] heapratio, Desired/Default Heap Ratio + def heap_size_calculator(membytes, heapratio) + memory_size_minified(membytes * heapratio) + end + + # Calculates the Memory Size in a Minified String Representation + # + # @param [Numeric] membytes, calculated heap size + def memory_size_minified(membytes) + giga = membytes / 2**(10 * 3) + mega = membytes / 2**(10 * 2) + kilo = (membytes / 2**(10 * 1)).round + if check_is_integer?(giga) + minified_size_calculator(giga, 'G') + elsif check_is_integer?(mega) + minified_size_calculator(mega, 'M') + elsif check_is_integer?(kilo) + minified_size_calculator(kilo, 'K') + end + end + + # Returns the minified memory string + # + # @param [Integer] order, calculated memory value + # @param [String] char, calculated memory unit + # @return [String] minified memory string + def minified_size_calculator(order, char) + order.to_i.to_s + char + end + + # Verifies whether heap ratio is valid + def heap_ratio_verification(ratio) + raise 'Invalid heap ratio' unless ratio.is_a? Numeric + raise 'heap ratio cannot be greater than 100%' unless ratio <= 1 + ratio + end + + end + + end +end diff --git a/spec/fixtures/stub-download.bin b/spec/fixtures/stub-download.bin new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/stub-java.bin b/spec/fixtures/stub-java.bin new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb b/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb new file mode 100644 index 0000000000..ebf64a5d16 --- /dev/null +++ b/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb @@ -0,0 +1,64 @@ +# Cloud Foundry Java Buildpack +# Copyright 2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/component/mutable_java_home' +require 'java_buildpack/jre/ibm_jre_initializer' + +describe JavaBuildpack::Jre::IbmJreInitializer do + include_context 'component_helper' + + let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } + + it 'detects with id of ibm-jre-initializer-' do + expect(component.detect).to eq("ibm-jre-initializer=#{version}") + end + + it 'installs java from bin', cache_fixture: 'stub-java.bin' do + component.detect + component.compile + + expect(sandbox + 'jre/bin/java').to exist + end + + it 'adds JAVA_HOME to java_home' do + component + + expect(java_home.root).to eq(sandbox + 'jre/') + end + + it 'adds java.io.tmpdir to java_opts' do + component.detect + component.release + + expect(java_opts).to include('-Djava.io.tmpdir=$TMPDIR') + end + + it 'adds Xtune to java_opts' do + component.detect + component.release + + expect(java_opts).to include('-Xtune:virtualized') + end + + it 'adds Xshareclasses to java_opts' do + component.detect + component.release + + expect(java_opts).to include('-Xshareclasses:none') + end + +end diff --git a/spec/java_buildpack/jre/ibm_jre_spec.rb b/spec/java_buildpack/jre/ibm_jre_spec.rb new file mode 100644 index 0000000000..83f57e2d09 --- /dev/null +++ b/spec/java_buildpack/jre/ibm_jre_spec.rb @@ -0,0 +1,70 @@ +# Cloud Foundry Java Buildpack +# Copyright 2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'fileutils' +require 'java_buildpack/component/mutable_java_home' +require 'java_buildpack/jre/ibm_jre_initializer' +require 'java_buildpack/jre/ibm_jre' + +describe JavaBuildpack::Jre::IbmJRE do + include_context 'component_helper' + + let(:component) { StubIbmJRE.new context } + + let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } + + let(:configuration) do + { 'jre' => jre_configuration, + 'jvmkill_agent' => jvmkill_agent_configuration } + end + + let(:jre_configuration) { instance_double('jre_configuration') } + + let(:jvmkill_agent_configuration) { {} } + + it 'supports anyway' do + expect(component.supports?).to be + end + + it 'creates IbmJreInitializer instance' do + allow_any_instance_of(StubIbmJRE).to receive(:supports?).and_return false + + allow(JavaBuildpack::Jre::IbmJreInitializer) + .to receive(:new).with(sub_configuration_context(jre_configuration).merge(component_name: 'Stub Ibm JRE')) + allow(JavaBuildpack::Jre::JvmkillAgent) + .to receive(:new).with(sub_configuration_context(jvmkill_agent_configuration)) + + component.sub_components context + end + +end + +class StubIbmJRE < JavaBuildpack::Jre::IbmJRE + + public :command, :sub_components + + def supports? + super + end + +end + +def sub_configuration_context(configuration) + cntxt = context.clone + cntxt[:configuration] = configuration + cntxt +end From afed86e11f35c7c190526bf44b7cbe388800950c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 30 May 2017 10:27:06 -0700 Subject: [PATCH 301/812] Polishing This change does some polishing to this contribution in order to bring it in line with current coding standard. Of note, this removes the jvmkill integration because the contributions needs to go into the 3.x branch where that does not exist. The jvmkill integration will be added back when this contribution is merged from 3.x to master. [resolves #427] --- README.md | 4 +- lib/java_buildpack/jre/ibm_jre.rb | 4 +- lib/java_buildpack/jre/ibm_jre_initializer.rb | 17 ++++--- resources/ibm_jre/bin/killjava.sh | 49 +++++++++++++++++++ spec/fixtures/stub-java.bin | 0 .../jre/ibm_jre_initializer_spec.rb | 8 +-- spec/java_buildpack/jre/ibm_jre_spec.rb | 9 +--- 7 files changed, 70 insertions(+), 21 deletions(-) create mode 100755 resources/ibm_jre/bin/killjava.sh mode change 100644 => 100755 spec/fixtures/stub-java.bin diff --git a/README.md b/README.md index 3ee7876ca1..edb186799f 100644 --- a/README.md +++ b/README.md @@ -96,10 +96,10 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Spring Insight](docs/framework-spring_insight.md) * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) * Standard JREs - * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) - * [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration)) * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) * [IBM® SDK, Java™ Technology Edition](docs/jre-ibm_jre.md) ([Configuration](docs/jre-ibm_jre.md#configuration)) + * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) + * [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration)) * [Extending](docs/extending.md) * [Application](docs/extending-application.md) * [Droplet](docs/extending-droplet.md) diff --git a/lib/java_buildpack/jre/ibm_jre.rb b/lib/java_buildpack/jre/ibm_jre.rb index a7404c71a4..168d0e9006 100644 --- a/lib/java_buildpack/jre/ibm_jre.rb +++ b/lib/java_buildpack/jre/ibm_jre.rb @@ -16,7 +16,6 @@ require 'java_buildpack/component/modular_component' require 'java_buildpack/jre' require 'java_buildpack/jre/ibm_jre_initializer' -require 'java_buildpack/jre/jvmkill_agent' require 'java_buildpack/jre/open_jdk_like_security_providers' module JavaBuildpack @@ -36,8 +35,7 @@ def command def sub_components(context) [ IbmJreInitializer.new(sub_configuration_context(context, 'jre') - .merge(component_name: self.class.to_s.space_case)), - JvmkillAgent.new(sub_configuration_context(context, 'jvmkill_agent')), + .merge(component_name: self.class.to_s.space_case)), OpenJDKLikeSecurityProviders.new(context) ] end diff --git a/lib/java_buildpack/jre/ibm_jre_initializer.rb b/lib/java_buildpack/jre/ibm_jre_initializer.rb index 4cecee65c9..e009f820ec 100644 --- a/lib/java_buildpack/jre/ibm_jre_initializer.rb +++ b/lib/java_buildpack/jre/ibm_jre_initializer.rb @@ -13,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -require 'digest' require 'fileutils' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/jre' @@ -60,9 +59,11 @@ def release @droplet .java_opts .add_system_property('java.io.tmpdir', '$TMPDIR') - @droplet.java_opts << '-Xtune:virtualized' + .add_option('-XX:OnOutOfMemoryError', killjava) + .add_preformatted_options('-Xtune:virtualized') + .add_preformatted_options('-Xshareclasses:none') + @droplet.java_opts.concat mem_opts - @droplet.java_opts << '-Xshareclasses:none' end private @@ -94,13 +95,13 @@ def install_bin(target_directory, file) # Returns the max heap size ('-Xmx') value def mem_opts - mopts = [] + mopts = [] total_memory = memory_limit_finder if total_memory.nil? # if no memory option has been set by cloudfoundry, we just assume defaults else calculated_heap_ratio = heap_ratio_verification(heap_ratio) - heap_size = heap_size_calculator(total_memory, calculated_heap_ratio) + heap_size = heap_size_calculator(total_memory, calculated_heap_ratio) mopts.push "-Xmx#{heap_size}" end mopts @@ -111,6 +112,10 @@ def heap_ratio @configuration['heap_ratio'] || HEAP_RATIO end + def killjava + @droplet.sandbox + 'jre/bin/killjava.sh' + end + # Returns the container total memory limit in bytes def memory_limit_finder memory_limit = ENV['MEMORY_LIMIT'] @@ -129,7 +134,7 @@ def memory_size_bytes(size) bytes = 0 else raise "Invalid memory size '#{size}'" if !size || size.length < 2 - unit = size[-1] + unit = size[-1] value = size[0..-2] raise "Invalid memory size '#{size}'" unless check_is_integer? value value = size.to_i diff --git a/resources/ibm_jre/bin/killjava.sh b/resources/ibm_jre/bin/killjava.sh new file mode 100755 index 0000000000..12facf5ecb --- /dev/null +++ b/resources/ibm_jre/bin/killjava.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# Cloud Foundry Java Buildpack +# Copyright (c) 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Kill script for use as the parameter of OpenJDK's -XX:OnOutOfMemoryError + +set -e + +echo " +Process Status (Before) +======================= +$(ps -ef) + +ulimit (Before) +=============== +$(ulimit -a) + +Free Disk Space (Before) +======================== +$(df -h) +" + +pkill -9 -f .*-XX:OnOutOfMemoryError=.*killjava.* + +echo " +Process Status (After) +====================== +$(ps -ef) + +ulimit (After) +============== +$(ulimit -a) + +Free Disk Space (After) +======================= +$(df -h) +" diff --git a/spec/fixtures/stub-java.bin b/spec/fixtures/stub-java.bin old mode 100644 new mode 100755 diff --git a/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb b/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb index ebf64a5d16..689db1106e 100644 --- a/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb @@ -27,11 +27,13 @@ expect(component.detect).to eq("ibm-jre-initializer=#{version}") end - it 'installs java from bin', cache_fixture: 'stub-java.bin' do + it 'installs java from bin', + cache_fixture: 'stub-java.bin' do + + allow(component).to receive(:shell).with(%r{spec/fixtures/stub-java.bin -i silent -f .* 2>&1}) + component.detect component.compile - - expect(sandbox + 'jre/bin/java').to exist end it 'adds JAVA_HOME to java_home' do diff --git a/spec/java_buildpack/jre/ibm_jre_spec.rb b/spec/java_buildpack/jre/ibm_jre_spec.rb index 83f57e2d09..3c34d1a13f 100644 --- a/spec/java_buildpack/jre/ibm_jre_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_spec.rb @@ -27,10 +27,7 @@ let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } - let(:configuration) do - { 'jre' => jre_configuration, - 'jvmkill_agent' => jvmkill_agent_configuration } - end + let(:configuration) { { 'jre' => jre_configuration } } let(:jre_configuration) { instance_double('jre_configuration') } @@ -45,8 +42,6 @@ allow(JavaBuildpack::Jre::IbmJreInitializer) .to receive(:new).with(sub_configuration_context(jre_configuration).merge(component_name: 'Stub Ibm JRE')) - allow(JavaBuildpack::Jre::JvmkillAgent) - .to receive(:new).with(sub_configuration_context(jvmkill_agent_configuration)) component.sub_components context end @@ -64,7 +59,7 @@ def supports? end def sub_configuration_context(configuration) - cntxt = context.clone + cntxt = context.clone cntxt[:configuration] = configuration cntxt end From 9325a285bc451db8cd4f3fcb40d4fded7acfd932 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 23 Jun 2017 10:06:40 -0700 Subject: [PATCH 302/812] Polishing --- spec/java_buildpack/jre/ibm_jre_spec.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/java_buildpack/jre/ibm_jre_spec.rb b/spec/java_buildpack/jre/ibm_jre_spec.rb index 3c34d1a13f..c54530a7c5 100644 --- a/spec/java_buildpack/jre/ibm_jre_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_spec.rb @@ -31,8 +31,6 @@ let(:jre_configuration) { instance_double('jre_configuration') } - let(:jvmkill_agent_configuration) { {} } - it 'supports anyway' do expect(component.supports?).to be end From 1f7695b2543b9a932efa4fa523a7eef9cb00e753 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 23 Jun 2017 10:11:25 -0700 Subject: [PATCH 303/812] Polishing --- config/ibm_jre.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/ibm_jre.yml b/config/ibm_jre.yml index f6659f7f7d..96dcb31683 100644 --- a/config/ibm_jre.yml +++ b/config/ibm_jre.yml @@ -20,6 +20,3 @@ jre: version: 1.8.+ repository_root: "https://raw.githubusercontent.com/ibmruntimes/ci.docker/master/ibmjava/meta/jre/linux/x86_64/" heap_ratio: 0.75 -jvmkill_agent: - version: 1.+ - repository_root: "https://raw.githubusercontent.com/ibmruntimes/jvmkill/jvmkill-ibmagent/jvmkill-agent/" From 94abd1b5693625e4423b45e3c6e95c692f9df066 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 23 Jun 2017 14:25:10 -0700 Subject: [PATCH 304/812] Update Introscope Agent Properties This change updates the Introscope Agent framework to add a new configuration property used by later versions of the agent. This change also re-works the code to be a bit more modern and reflect current coding styles. [resolves #449] --- .../framework/introscope_agent.rb | 78 ++++++++++++------- .../framework/introscope_agent_spec.rb | 7 +- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index a92c479836..00537200cb 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -34,16 +34,18 @@ def compile def release credentials = @application.services.find_service(FILTER)['credentials'] java_opts = @droplet.java_opts - java_opts.add_javaagent(@droplet.sandbox + 'Agent.jar') - java_opts.add_system_property('com.wily.introscope.agentProfile', - @droplet.sandbox + 'core/config/IntroscopeAgent.profile') - - agent_host_name java_opts - agent_name java_opts, credentials - default_process_name java_opts - host_name java_opts, credentials - port java_opts, credentials - ssl_socket_factory java_opts, credentials + + java_opts + .add_javaagent(agent_jar) + .add_system_property('com.wily.introscope.agentProfile', agent_profile) + .add_system_property('introscope.agent.hostName', agent_host_name) + .add_system_property('com.wily.introscope.agent.agentName', agent_name(credentials)) + .add_system_property('introscope.agent.defaultProcessName', default_process_name) + .add_system_property('introscope.agent.enterprisemanager.transport.tcp.host.DEFAULT', host_name(credentials)) + .add_system_property('agentManager.url.1', agent_manager(credentials)) + + add_port(credentials, java_opts) + add_socket_factory(credentials, java_opts) end protected @@ -59,35 +61,55 @@ def supports? private_constant :FILTER - def agent_host_name(java_opts) - java_opts.add_system_property('introscope.agent.hostName', @application.details['application_uris'][0]) + def add_port(credentials, java_opts) + port = port(credentials) + java_opts.add_system_property('introscope.agent.enterprisemanager.transport.tcp.port.DEFAULT', port) if port + end + + def add_socket_factory(credentials, java_opts) + return unless ssl?(credentials) + java_opts.add_system_property('introscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT', + 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') end - def agent_name(java_opts, credentials) - name = credentials['agent-name'] || @configuration['default_agent_name'] - java_opts.add_system_property('com.wily.introscope.agent.agentName', name.to_s) + def agent_host_name + @application.details['application_uris'][0] end - def default_process_name(java_opts) - java_opts.add_system_property('introscope.agent.defaultProcessName', @application.details['application_name']) + def agent_jar + @droplet.sandbox + 'Agent.jar' + end + + def agent_manager(credentials) + agent_manager = ssl?(credentials) ? 'https://' : 'http://' + agent_manager += host_name(credentials) + + port = port(credentials) + port ? "#{agent_manager}:#{port}" : agent_manager end - def host_name(java_opts, credentials) - host_name = credentials['host-name'] - raise "'host-name' credential must be set" unless host_name - java_opts.add_system_property 'introscope.agent.enterprisemanager.transport.tcp.host.DEFAULT', host_name + def agent_name(credentials) + credentials['agent-name'] || @configuration['default_agent_name'] end - def port(java_opts, credentials) - port = credentials['port'] - java_opts.add_system_property 'introscope.agent.enterprisemanager.transport.tcp.port.DEFAULT', port if port + def agent_profile + @droplet.sandbox + 'core/config/IntroscopeAgent.profile' end - def ssl_socket_factory(java_opts, credentials) - return unless credentials['ssl'].to_b + def default_process_name + @application.details['application_name'] + end + + def host_name(credentials) + credentials['host-name'] + end + + def port(credentials) + credentials['port'] + end - java_opts.add_system_property 'introscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT', - 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory' + def ssl?(credentials) + credentials['ssl'].to_b end end diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index 958355f63e..0dfc9f8761 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -54,10 +54,6 @@ expect(sandbox + 'Agent.jar').to exist end - it 'raises error if host-name not specified' do - expect { component.release }.to raise_error(/'host-name' credential must be set/) - end - context do let(:credentials) { { 'host-name' => 'test-host-name' } } @@ -71,6 +67,7 @@ expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-DagentManager.url.1=http://test-host-name') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end @@ -92,6 +89,7 @@ component.release expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=test-port') + expect(java_opts).to include('-DagentManager.url.1=http://test-host-name:test-port') end end @@ -103,6 +101,7 @@ expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') + expect(java_opts).to include('-DagentManager.url.1=https://test-host-name') end end end From 841ecb24e5fe9542e79ed646bffeb97551f6f150 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Sat, 24 Jun 2017 08:12:21 -0700 Subject: [PATCH 305/812] Polishing --- config/contrast_security_agent.yml | 2 +- config/ibm_jre.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index 855aff80eb..19ff50871a 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -16,4 +16,4 @@ # Configuration for the ContrastSecurity framework --- version: 3.+ -repository_root: "https://artifacts.contrastsecurity.com/agents/java/" +repository_root: https://artifacts.contrastsecurity.com/agents/java diff --git a/config/ibm_jre.yml b/config/ibm_jre.yml index 96dcb31683..ca92ec73cc 100644 --- a/config/ibm_jre.yml +++ b/config/ibm_jre.yml @@ -18,5 +18,5 @@ --- jre: version: 1.8.+ - repository_root: "https://raw.githubusercontent.com/ibmruntimes/ci.docker/master/ibmjava/meta/jre/linux/x86_64/" + repository_root: https://raw.githubusercontent.com/ibmruntimes/ci.docker/master/ibmjava/meta/jre/linux/x86_64 heap_ratio: 0.75 From d6c598cf0d8fe0a00ecb77657484a0b2da3416fc Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 3 Jul 2017 13:00:24 +0100 Subject: [PATCH 306/812] Polishing --- docs/jre-open_jdk_jre.md | 4 ++-- docs/jre-oracle_jre.md | 4 ++-- docs/jre-zulu_jre.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index a0b4385cb5..7df3e27f73 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -69,10 +69,10 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `"/-/-/--.hprof` +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain -Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39-b546-41d9-8095-9a45fa65df9e/java-main-application-892f20ab-9a53-441d-be3e-72c38f2a1055/0-2017-06-13T18:31:29+0000-7b23124e-7f0f-4a08-457b-60802d0a7326.hprof +Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof ``` ### Memory diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index b1edb8d005..1edbde09f6 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -85,10 +85,10 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `"/-/-/--.hprof` +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain -Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39-b546-41d9-8095-9a45fa65df9e/java-main-application-892f20ab-9a53-441d-be3e-72c38f2a1055/0-2017-06-13T18:31:29+0000-7b23124e-7f0f-4a08-457b-60802d0a7326.hprof +Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof ``` ### Memory diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index 8e2e21a405..8a6428d65d 100755 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -76,10 +76,10 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `"/-/-/--.hprof` +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain -Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39-b546-41d9-8095-9a45fa65df9e/java-main-application-892f20ab-9a53-441d-be3e-72c38f2a1055/0-2017-06-13T18:31:29+0000-7b23124e-7f0f-4a08-457b-60802d0a7326.hprof +Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof ``` ### Memory From 7b44e864e39a5eb4ec830e4d1f241a3a5e8d6bba Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 4 Jul 2017 09:41:51 +0100 Subject: [PATCH 307/812] Add Concourse Caching --- ci/auto-merge.sh | 2 +- ci/package-test.sh | 3 ++- ci/package-test.yml | 3 +++ ci/unit-test.sh | 3 ++- ci/unit-test.yml | 3 +++ ci/versions-markdown.sh | 3 ++- ci/versions-markdown.yml | 3 +++ ci/versions-pivotal-network.sh | 3 ++- ci/versions-pivotal-network.yml | 3 +++ ci/versions-yaml.sh | 3 ++- ci/versions-yaml.yml | 3 +++ ci/versions.sh | 3 ++- ci/versions.yml | 3 +++ 13 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ci/auto-merge.sh b/ci/auto-merge.sh index 3a3e7af2c8..bf05431e7b 100755 --- a/ci/auto-merge.sh +++ b/ci/auto-merge.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -e -u pushd upstream COMMIT=$(git rev-parse HEAD) diff --git a/ci/package-test.sh b/ci/package-test.sh index 439c8e4f96..d2870277e1 100755 --- a/ci/package-test.sh +++ b/ci/package-test.sh @@ -14,8 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -e -u +export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 diff --git a/ci/package-test.yml b/ci/package-test.yml index 90aa50576e..54239e4bfe 100644 --- a/ci/package-test.yml +++ b/ci/package-test.yml @@ -23,5 +23,8 @@ image_resource: inputs: - name: java-buildpack +caches: +- path: gems + run: path: java-buildpack/ci/package-test.sh diff --git a/ci/unit-test.sh b/ci/unit-test.sh index 215cefb442..976c25f6e2 100755 --- a/ci/unit-test.sh +++ b/ci/unit-test.sh @@ -14,8 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -e -u +export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 diff --git a/ci/unit-test.yml b/ci/unit-test.yml index 0f09b3616f..931e7d6d47 100644 --- a/ci/unit-test.yml +++ b/ci/unit-test.yml @@ -23,6 +23,9 @@ image_resource: inputs: - name: java-buildpack +caches: +- path: gems + run: path: java-buildpack/ci/unit-test.sh diff --git a/ci/versions-markdown.sh b/ci/versions-markdown.sh index 0b473fdfc0..05caeb1e7e 100755 --- a/ci/versions-markdown.sh +++ b/ci/versions-markdown.sh @@ -14,8 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -e -u +export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 diff --git a/ci/versions-markdown.yml b/ci/versions-markdown.yml index 84071d43e2..7055f8d1bb 100644 --- a/ci/versions-markdown.yml +++ b/ci/versions-markdown.yml @@ -23,5 +23,8 @@ image_resource: inputs: - name: java-buildpack +caches: +- path: gems + run: path: java-buildpack/ci/versions-markdown.sh diff --git a/ci/versions-pivotal-network.sh b/ci/versions-pivotal-network.sh index 6c0cfebe67..9eddac80c2 100755 --- a/ci/versions-pivotal-network.sh +++ b/ci/versions-pivotal-network.sh @@ -14,8 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -e -u +export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 diff --git a/ci/versions-pivotal-network.yml b/ci/versions-pivotal-network.yml index 978fe4b5ed..d832f11836 100644 --- a/ci/versions-pivotal-network.yml +++ b/ci/versions-pivotal-network.yml @@ -23,5 +23,8 @@ image_resource: inputs: - name: java-buildpack +caches: +- path: gems + run: path: java-buildpack/ci/versions-pivotal-network.sh diff --git a/ci/versions-yaml.sh b/ci/versions-yaml.sh index 70b8d61c46..cc6acb2c34 100755 --- a/ci/versions-yaml.sh +++ b/ci/versions-yaml.sh @@ -14,8 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -e -u +export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 diff --git a/ci/versions-yaml.yml b/ci/versions-yaml.yml index d9dee887de..4d60eabb0f 100644 --- a/ci/versions-yaml.yml +++ b/ci/versions-yaml.yml @@ -23,5 +23,8 @@ image_resource: inputs: - name: java-buildpack +caches: +- path: gems + run: path: java-buildpack/ci/versions-yaml.sh diff --git a/ci/versions.sh b/ci/versions.sh index 35ae58c16f..093624c7f3 100755 --- a/ci/versions.sh +++ b/ci/versions.sh @@ -14,8 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -e -u +export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 diff --git a/ci/versions.yml b/ci/versions.yml index 2968dc4495..a1ae8193e1 100644 --- a/ci/versions.yml +++ b/ci/versions.yml @@ -23,5 +23,8 @@ image_resource: inputs: - name: java-buildpack +caches: +- path: gems + run: path: java-buildpack/ci/versions.sh From 71c8c9b023b5908d5ac595f4984242ec98e8833f Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Sat, 24 Jun 2017 22:09:52 +0200 Subject: [PATCH 308/812] Update JRE documentation This change updates the JRE documentation so that the use of short IDs is properly described. [resolve #452] --- docs/jre-open_jdk_jre.md | 2 +- docs/jre-oracle_jre.md | 2 +- docs/jre-zulu_jre.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 7df3e27f73..ac80460de3 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -69,7 +69,7 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 1edbde09f6..360f6d67fa 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -85,7 +85,7 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index 8a6428d65d..5910281838 100755 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -76,7 +76,7 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` +If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof From d70bd47684b2d169dd0bd5347df2a962ae8de3ba Mon Sep 17 00:00:00 2001 From: Cade Thacker Date: Tue, 27 Jun 2017 12:21:31 -0400 Subject: [PATCH 309/812] Update AppDynamics Repository Link This change updates the link to the AppDynamics repository index. [resolves #454] --- docs/framework-app_dynamics_agent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 8a4fe5e232..2803ee83fb 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -49,5 +49,5 @@ The framework can also be configured by overlaying a set of resources on the def [AppDynamics Service]: http://www.appdynamics.com [Configuration and Extension]: ../README.md#configuration-and-extension [repositories]: extending-repositories.md -[this listing]: http://download.pivotal.io.s3.amazonaws.com/app-dynamics/index.yml +[this listing]: https://packages.appdynamics.com/java/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering From dbf9a9044a0d01b91dcc8c049fdf0ff2a005243e Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 4 Jul 2017 16:19:55 +0100 Subject: [PATCH 310/812] Versions Improvements This change improves the output of the versions:markdown and changes the versions:pivotal_network to a more generic versions:json that has a payload suitable for Pivotal Network. --- ...ns-pivotal-network.sh => versions-json.sh} | 2 +- ...-pivotal-network.yml => versions-json.yml} | 2 +- rakelib/versions_task.rb | 24 +++++++++++-------- 3 files changed, 16 insertions(+), 12 deletions(-) rename ci/{versions-pivotal-network.sh => versions-json.sh} (95%) rename ci/{versions-pivotal-network.yml => versions-json.yml} (93%) diff --git a/ci/versions-pivotal-network.sh b/ci/versions-json.sh similarity index 95% rename from ci/versions-pivotal-network.sh rename to ci/versions-json.sh index 9eddac80c2..ac6e32c9e1 100755 --- a/ci/versions-pivotal-network.sh +++ b/ci/versions-json.sh @@ -25,5 +25,5 @@ eval "$(rbenv init -)" pushd java-buildpack bundle install --quiet - bundle exec rake versions:pivotal_network + bundle exec rake versions:json popd diff --git a/ci/versions-pivotal-network.yml b/ci/versions-json.yml similarity index 93% rename from ci/versions-pivotal-network.yml rename to ci/versions-json.yml index d832f11836..89f3fc801c 100644 --- a/ci/versions-pivotal-network.yml +++ b/ci/versions-json.yml @@ -27,4 +27,4 @@ caches: - path: gems run: - path: java-buildpack/ci/versions-pivotal-network.sh + path: java-buildpack/ci/versions-json.sh diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index fe1baebd6e..e33ff2bc4c 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -19,6 +19,7 @@ require 'java_buildpack/repository/version_resolver' require 'java_buildpack/util/configuration_utils' require 'java_buildpack/util/cache/download_cache' +require 'json' require 'rake/tasklib' require 'rakelib/package' require 'terminal-table' @@ -35,8 +36,8 @@ def initialize version_task namespace 'versions' do + version_json_task version_markdown_task - version_pivotal_network_task version_yaml_task end end @@ -221,21 +222,24 @@ def version_task end end - def version_markdown_task - desc 'Display the versions of buildpack dependencies in Markdown form' - task markdown: [] do - versions['dependencies'] + def version_json_task + desc 'Display the versions of buildpack dependencies in JSON form' + task json: [] do + puts JSON.pretty_generate(versions['dependencies'] .sort_by { |dependency| dependency['name'].downcase } - .each { |dependency| puts "| #{dependency['name']} | `#{dependency['version']}` |" } + .map { |dependency| "#{dependency['name']} #{dependency['version']}" }) end end - def version_pivotal_network_task - desc 'Display the versions of buildpack dependencies in Pivotal Network form' - task pivotal_network: [] do + def version_markdown_task + desc 'Display the versions of buildpack dependencies in Markdown form' + task markdown: [] do + puts '| Dependency | Version |' + puts '| ---------- | ------- |' + versions['dependencies'] .sort_by { |dependency| dependency['name'].downcase } - .each { |dependency| puts "#{dependency['name']} #{dependency['version']}" } + .each { |dependency| puts "| #{dependency['name']} | `#{dependency['version']}` |" } end end From f2eee8503d6133f4a165d345428aadf49c295b68 Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Wed, 26 Oct 2016 23:34:43 +0200 Subject: [PATCH 311/812] Java Memory Assistant This changes adds a Java Memory Assistant Framework to the buildpack. This buildpack automatically creates heapdumps based on configuration thresholds and memory consumption patterns. It can write these heap dumps to the container ephemeral file system or to file systems exposed via volume services. [#436] --- README.md | 1 + config/components.yml | 1 + config/java_memory_assistant.yml | 36 +++ docs/framework-java_memory_assistant.md | 115 +++++++++ .../framework/java_memory_assistant.rb | 51 ++++ .../framework/java_memory_assistant/agent.rb | 102 ++++++++ .../java_memory_assistant/clean_up.rb | 55 +++++ .../java_memory_assistant/heap_dump_folder.rb | 86 +++++++ .../stub-java-memory-assistant-cleanup.zip | Bin 0 -> 140 bytes .../java_memory_assistant/agent_spec.rb | 223 ++++++++++++++++++ .../java_memory_assistant/clean_up_spec.rb | 97 ++++++++ .../heap_dump_folder_spec.rb | 131 ++++++++++ .../framework/java_memory_assistant_spec.rb | 73 ++++++ 13 files changed, 971 insertions(+) create mode 100644 config/java_memory_assistant.yml create mode 100644 docs/framework-java_memory_assistant.md create mode 100644 lib/java_buildpack/framework/java_memory_assistant.rb create mode 100644 lib/java_buildpack/framework/java_memory_assistant/agent.rb create mode 100644 lib/java_buildpack/framework/java_memory_assistant/clean_up.rb create mode 100644 lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb create mode 100644 spec/fixtures/stub-java-memory-assistant-cleanup.zip create mode 100644 spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb create mode 100644 spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb create mode 100644 spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb create mode 100644 spec/java_buildpack/framework/java_memory_assistant_spec.rb diff --git a/README.md b/README.md index edb186799f..6a77df0546 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) * [Google Stackdriver Debugger](docs/framework-google_stackdriver_debugger.md) ([Configuration](docs/framework-google_stackdriver_debugger.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) + * [Java Memory Assistant](docs/framework-java_memory_assistant.md) ([Configuration](docs/framework-java_memory_assistant.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) * [JMX](docs/framework-jmx.md) ([Configuration](docs/framework-jmx.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 773ce228b7..0b42b12d13 100644 --- a/config/components.yml +++ b/config/components.yml @@ -48,6 +48,7 @@ frameworks: - "JavaBuildpack::Framework::DynatraceOneAgent" - "JavaBuildpack::Framework::GoogleStackdriverDebugger" # - "JavaBuildpack::Framework::IntroscopeAgent" + - "JavaBuildpack::Framework::JavaMemoryAssistant" - "JavaBuildpack::Framework::Jmx" - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::LunaSecurityProvider" diff --git a/config/java_memory_assistant.yml b/config/java_memory_assistant.yml new file mode 100644 index 0000000000..21fd798c19 --- /dev/null +++ b/config/java_memory_assistant.yml @@ -0,0 +1,36 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +enabled: false +agent: + version: 0.+ + repository_root: https://raw.githubusercontent.com/SAP/java-memory-assistant/repository + heap_dump_folder: + check_interval: 5s + max_frequency: 1/1m + log_level: + thresholds: + heap: + code_cache: + metaspace: + perm_gen: + compressed_class: + eden: + survivor: + old_gen: ">600MB" +clean_up: + version: 0.+ + repository_root: https://raw.githubusercontent.com/SAP/java-memory-assistant-tools/repository-cu + max_dump_count: 1 \ No newline at end of file diff --git a/docs/framework-java_memory_assistant.md b/docs/framework-java_memory_assistant.md new file mode 100644 index 0000000000..7e2ad936de --- /dev/null +++ b/docs/framework-java_memory_assistant.md @@ -0,0 +1,115 @@ +# Java Memory Assistant Framework +The Java Memory Assistant is a Java agent (as in `-javaagent`) that creats heap dumps of your application automatically based on preconfigured conditions of memory usage. +The heap dumps created by the Java Memory Assistant can be analyzed using Java memory profilers that support the `.hprof` format (i.e., virtually all profilers). + + + + + + + + +
Detection Criterionenabled set in the config/java_memory_assistant.yml
Tagsjava-memory-assistant=<version>
+Tags are printed to standard output by the buildpack detect script. + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [``config/java_memory_assistant.yml``][] file in the buildpack fork. + +| Name | Description +| ---- | ----------- +| `enabled` | Whether to enable the Java Memory Assistant framework. By default the agent is turned off. +| `agent.heap_dump_folder` | The folder on the container's filesystem where heap dumps are created. Default value: `$PWD` +| `agent.thresholds.` | This configuration allows to define thresholds for every memory area of the JVM. Thresholds can be defined in absolute percentages, e.g., `75%` creates a heap dump at 75% of the selected memory area. It is also possible to specify relative increases and decreases of memory usage: for example, `+5%/2m` will triggera heap dumpo if the particular memory area has increased by `5%` or more over the last two minutes. See below to check which memory areas are supported. Since version `0.3.0`, thresholds can also be specified in terms of absolute values, e.g., `>400MB` (more than 400 MB) or `<=30KB` (30 KB or less); supported memory size units are `KB`, `MB` and `GB`. +| `agent.check_interval` | The interval between checks. Examples: `1s` (once a second), `3m` (every three minutes), `1h` (once every hour). Default: `5s` (check every five seconds). +| `agent.max_frequency` | Maximum amount of heap dumps that the Java Memory Assistant is allowed to create in a given amount of time. Examples: `1/30s` (no more than one heap dump every thirty seconds), `2/3m` (up to two heap dumps every three minutes), `1/2h` (one heap dump every two hours). The time interval is checked every time one heap dump *should* be created (based on the specified thresholds), and compared with the timestamps of the previously created heap dumps to make sure that the maximum frequency is not exceeded. Default: `1/1m` (one heap dump per minute). | +| `agent.log_level` | The log level used by the Java Memory Assistant. Supported values are the same as the Java buildpack's: `DEBUG`, `WARN`, `INFO`, `ERROR` and `FATAL` (the latter is equivalent to `ERROR`). If the `agent.log_level` is not specified, the Java buildpack's log level will be used. | +| `clean_up.max_dump_count` | Maximum amount of heap dumps that can be stored in the filesystem of the container; when the creation of a new heap dump would cause the threshold to be surpassed, the oldest heap dumps are removed from the file system. Default value: `1` | + +### Heap Dump Names + +The heap dump filenames will be generated according to the following name pattern: + +`-%ts:yyyyMMdd'T'mmssSSSZ%-.hprof` + +The timestamp pattern `%ts:yyyyMMdd'T'mmssSSSZ%` is equivalent to the `%FT%T%z` pattern of [strftime](http://www.cplusplus.com/reference/ctime/strftime/) for [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). + +### Supported Memory Areas + +| Memory Area | Property Name | +|------------------------|------------------| +| Heap | `heap` | +| Code Cache | `code_cache` | +| Metaspace | `metaspace` | +| Compressed Class Space | `compressed_class` | +| Eden | `eden` | +| Survivor | `survivor` | +| Old Generation | `old_gen` | + +The default values can be found in the [``config/java_memory_assistant.yml``][] file. + +### Examples + +Enable the Java Memory Assistant with its default settings: + +```yaml +JBP_CONFIG_JAVA_MEMORY_ASSISTANT: '{enabled : true}' +``` + +Create heap dumps when the old generation memory pool exceeds 800 MB: + +```yaml +JBP_CONFIG_JAVA_MEMORY_ASSISTANT: '{enabled : true, agent: { thresholds : { old_gen : ">800MB" } } }' +``` + +Create heap dumps when the old generation grows by more than 20% in two minutes: + +```yaml +JBP_CONFIG_JAVA_MEMORY_ASSISTANT: '{enabled : true, agent : { thresholds : { old_gen : +20%/2m } } }' +``` + +### What are the right thresholds for your application? + +Well, it depends. +The way applications behave in terms of memory management is a direct result of how they are implemented. +This is much more then case when the applications are under heavy load. +Thus, there is no "silver bullet" configuration that will serve all applications equally well, and Java Memory Assistant configurations should result from profiling the application under load and then encode the expected memory usage patterns (plus a margin upwards) to detect anomalies. + +Nevertheless, a memory area that tends to be particularly interesting to monitor is the so called "old generation" (`old_gen`). +When instantiated, bjects in the Java heap are allocated in an area called `eden`. +As garbage collections occur, objects that are not reclaimed become first "survivors" (and belong to the namesake `survivor` memory area) and then eventually become `old_gen`. +In other words, `old_gen` objects are those that survived multiple garbage collections. +In contrast, `eden` and `survivor` objects are collectively called "young generation". + +Application-wide singletons and pooled objects (threads, connections) are examples of "legitimate" `old_gen` candidates. +But memory leaks, by their very nature or surviving multiple garbage collections, end up in `old_gen` too. +Under load that is not too high for the application (and you should find out what it is with load tests and avoid it via rate limiting, e.g., using [route services](https://docs.cloudfoundry.org/services/route-services.html) in front of your application), Java code that allows the JVM to perform efficient memory management tends to have a rather consistent baseline of `old_gen` objects, with most objects being reclaimed as they are still young generation. +That is, when the `old_gen` grows large with respect to the overall heap, this often signifies some sort of memory leak or, at the very least, suboptimal memory management. +Notable exceptions to this rule of thumb are applications that use large local caches. + +### Making sure heap dumps can be created + +The Java Virtual Machine must create heap dumps on a file. +Unless you are using a `volume service`, it pretty much means that, even if you are uploading the heap dump somewhere else, the heap dump must first land on the ephemeral disk of the container. +Ephemeral disks have quotas and, if all the space is taken by heap dumps (even incomplete ones!), horrible things are bound to happen to your app. + +The maximum size of a heap dump depends on the maximum size of the heap of the Java Virtual Machine. +Consider increasing the disk quota of your warden/garden container via the `cf scale -k [new size]` using as `new size` to the outcome of the following calculation: + +`[max heap size] * [max heap dump count] + 200MB` + +The aditional `200MB` is a rule-of-thumb, generous over-approximation of the amount of disk the buildpack and the application therein needs to run. +If your application requires more filesystem than just a few tens of megabytes, you must increase the additional portion of the disk amount calculation accordingly. + +### Where to best store heap dumps? + +Heap dumps are created by the Java Virtual Machine on a file on the filesystem mounted by the garden container. +Normally, the filesystem of a container is ephemeral. +That is, if your app crashes or it is shut down, the filesystem of its container is gone with it and so are your heap dumps. + +To prevent heap dumps from "going down" with the container, you should consider storing them on a `volume service`. + +#### Container-mounted volumes + +If you are using a filesystem service that mounts persistent volumes to the container, it is enough to name one of the volume services `heap-dump` or tag one volume with `heap-dump`, and the path specified as the `heap_dump_folder` configuration will be resolved against `/-/-`. \ No newline at end of file diff --git a/lib/java_buildpack/framework/java_memory_assistant.rb b/lib/java_buildpack/framework/java_memory_assistant.rb new file mode 100644 index 0000000000..1e5522ad73 --- /dev/null +++ b/lib/java_buildpack/framework/java_memory_assistant.rb @@ -0,0 +1,51 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/modular_component' +require 'java_buildpack/framework' +require 'java_buildpack/framework/java_memory_assistant/agent' +require 'java_buildpack/framework/java_memory_assistant/clean_up' +require 'java_buildpack/framework/java_memory_assistant/heap_dump_folder' + +module JavaBuildpack + module Framework + + # Encapsulates the integraton of the JavaMemoryAssistant. + class JavaMemoryAssistant < JavaBuildpack::Component::ModularComponent + + protected + + # (see JavaBuildpack::Component::ModularComponent#command) + def command + # Nothing to do here, the agent is initialized via java opts + end + + # (see JavaBuildpack::Component::ModularComponent#sub_components) + def sub_components(context) + [ + JavaMemoryAssistantAgent.new(sub_configuration_context(context, 'agent')), + JavaMemoryAssistantHeapDumpFolder.new(sub_configuration_context(context, 'agent')), + JavaMemoryAssistantCleanUp.new(sub_configuration_context(context, 'clean_up')) + ] + end + + # (see JavaBuildpack::Component::ModularComponent#supports?) + def supports? + @configuration['enabled'] + end + + end + end +end diff --git a/lib/java_buildpack/framework/java_memory_assistant/agent.rb b/lib/java_buildpack/framework/java_memory_assistant/agent.rb new file mode 100644 index 0000000000..363944d038 --- /dev/null +++ b/lib/java_buildpack/framework/java_memory_assistant/agent.rb @@ -0,0 +1,102 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/component/droplet' +require 'java_buildpack/component/environment_variables' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the integraton of the JavaMemoryAssistant to inject the agent in the JVM. + class JavaMemoryAssistantAgent < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts.add_javaagent @droplet.sandbox + jar_name + + @droplet.java_opts.add_system_property 'jma.enabled', 'true' + @droplet.java_opts.add_system_property 'jma.heap_dump_name', %("#{name_pattern}") + + add_system_prop_if_config_present 'check_interval', 'jma.check_interval' + add_system_prop_if_config_present 'max_frequency', 'jma.max_frequency' + + @droplet.java_opts.add_system_property 'jma.log_level', log_level + + (@configuration['thresholds'] || {}).each do |key, value| + @droplet.java_opts.add_system_property "jma.thresholds.#{key}", value.to_s + end + end + + protected + + def supports? + true + end + + # (see JavaBuildpack::Component::VersionedDependencyComponent#jar_name) + def jar_name + "java-memory-assistant-#{@version}.jar" + end + + private + + def name_pattern + # Double escaping quotes of doom. Nothing less would work. + %q(%env:CF_INSTANCE_INDEX%-%ts:yyyy-MM-dd'"'"'T'"'"'mm'"'"':'"'"'ss'"'"':'"'"'SSSZ%-) \ + '%env:CF_INSTANCE_GUID[,8]%.hprof' + end + + def add_system_prop_if_config_present(config_entry, system_property_name, quote_value = false) + return unless @configuration[config_entry] + + config_value = @configuration[config_entry] + config_value = '"' + config_value + '"' if quote_value + + @droplet.java_opts.add_system_property(system_property_name, config_value) + end + + def log_level + actual_log_level = @configuration['log_level'] || ENV['JBP_LOG_LEVEL'] || 'ERROR' + + mapped_log_level = log_level_mapping[actual_log_level.upcase] + + raise "Invalid value of the 'log_level' property: '#{actual_log_level}'" unless mapped_log_level + + mapped_log_level + end + + def log_level_mapping + { + 'DEBUG' => 'DEBUG', + 'WARN' => 'WARNING', + 'INFO' => 'INFO', + 'ERROR' => 'ERROR', + 'FATAL' => 'ERROR' + } + end + + end + end +end diff --git a/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb b/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb new file mode 100644 index 0000000000..7bd24853aa --- /dev/null +++ b/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb @@ -0,0 +1,55 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/component/droplet' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the integraton of the JavaMemoryAssistant to set up clean up of dumps. + class JavaMemoryAssistantCleanUp < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + return unless supports? + + download_zip false + + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + return unless supports? + + environment_variables = @droplet.environment_variables + environment_variables.add_environment_variable 'JMA_MAX_DUMP_COUNT', @configuration['max_dump_count'].to_s + + @droplet.java_opts.add_system_property('jma.command.interpreter', '') + @droplet.java_opts.add_system_property('jma.execute.before', @droplet.sandbox + 'cleanup') + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @configuration['max_dump_count'].to_i > 0 + end + + end + end +end diff --git a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb new file mode 100644 index 0000000000..1a2316d4c8 --- /dev/null +++ b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb @@ -0,0 +1,86 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/base_component' +require 'java_buildpack/component/droplet' +require 'java_buildpack/framework' +require 'java_buildpack/framework/java_memory_assistant' + +module JavaBuildpack + module Framework + + # Encapsulates the integraton of the JavaMemoryAssistant to store generated heap dumps. + class JavaMemoryAssistantHeapDumpFolder < JavaBuildpack::Component::BaseComponent + + # Creates an instance + # + # @param [Hash] context a collection of utilities used by the component + def initialize(context) + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger JavaMemoryAssistantHeapDumpFolder + super(context) + end + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + true + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + # Nothing to do + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + environment_variables = @droplet.environment_variables + + heap_dump_folder = @configuration['heap_dump_folder'] || default_heap_dump_folder + + # If there is a bound volume service, use the heap_dump_folder under the volume's path + service = find_heap_dump_volume_service + if service + volume_mount = service['volume_mounts'][0] + container_dir = volume_mount['container_dir'] + mode = volume_mount['mode'] + + raise "Volume mounted under '#{container_dir}' not in write mode" unless mode.to_s.include? 'w' + + heap_dump_folder = "#{container_dir}/#{heap_dump_folder}" + @logger.info { "Using volume service mounted under '#{container_dir}' to store heap dumps" } + end + + # This is needed by the clean_up module + environment_variables.add_environment_variable 'JMA_HEAP_DUMP_FOLDER', heap_dump_folder.to_s + @droplet.java_opts.add_system_property 'jma.heap_dump_folder', "\"#{heap_dump_folder}\"" + @logger.info { "Heap dumps will be stored under '#{heap_dump_folder}'" } + end + + private + + # Matcher for service names or tags associated with the Java Memory Assistant + FILTER = 'heap-dump'.freeze + + def find_heap_dump_volume_service + @application.services.find_service FILTER + end + + def default_heap_dump_folder + "#{@application.details['space_name']}-#{@application.details['space_id'][0...8]}/" \ + "#{@application.details['application_name']}-#{@application.details['application_id'][0...8]}" + end + + end + end +end diff --git a/spec/fixtures/stub-java-memory-assistant-cleanup.zip b/spec/fixtures/stub-java-memory-assistant-cleanup.zip new file mode 100644 index 0000000000000000000000000000000000000000..b7a42c4d25d7143a81af5f5f99111320614c18d1 GIT binary patch literal 140 zcmWIWW@h1H0D*IR&Ut|uP=cL7fFU_2H8HQWAT)x9L2IjH '42', + 'instance_id' => '406beca7-7692-41f4-9482-f32ae0a1da93' + } + end + + context do + + let(:configuration) do + { + 'check_interval' => '5s', + 'max_frequency' => '1/1m', + 'thresholds' => { + 'heap' => 90, + 'old_gen' => 90 + } + } + end + + let(:version) { '1.2.3' } + + it 'updates JAVA_OPTS with default values' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ + 'java-memory-assistant-1.2.3.jar') + expect(java_opts).to include('-Djma.enabled=true') + + expect(java_opts).to include('-Djma.check_interval=5s') + expect(java_opts).to include('-Djma.max_frequency=1/1m') + + expect(java_opts).to include('-Djma.thresholds.heap=90') + expect(java_opts).to include('-Djma.thresholds.old_gen=90') + end + + end + + context do + let(:configuration) do + { + 'check_interval' => '10m', + 'max_frequency' => '4/10h', + 'heap_dump_folder' => 'test/folder', + 'log_level' => 'DEBUG', + 'thresholds' => { + 'heap' => 60, + 'code_cache' => 30, + 'metaspace' => 5, + 'perm_gen' => 45.5, + 'eden' => 90, + 'survivor' => 95.5, + 'old_gen' => 30 + } + } + end + + let(:version) { '0.1.0' } + + it 'updates JAVA_OPTS with configured values' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ + 'java-memory-assistant-0.1.0.jar') + expect(java_opts).to include('-Djma.enabled=true') + expect(java_opts).to include('-Djma.check_interval=10m') + expect(java_opts).to include('-Djma.max_frequency=4/10h') + expect(java_opts).to include('-Djma.log_level=DEBUG') + expect(java_opts).to include('-Djma.thresholds.heap=60') + expect(java_opts).to include('-Djma.thresholds.code_cache=30') + expect(java_opts).to include('-Djma.thresholds.metaspace=5') + expect(java_opts).to include('-Djma.thresholds.perm_gen=45.5') + expect(java_opts).to include('-Djma.thresholds.eden=90') + expect(java_opts).to include('-Djma.thresholds.survivor=95.5') + expect(java_opts).to include('-Djma.thresholds.old_gen=30') + end + + end + + context do + let(:configuration) do + { + 'log_level' => 'debug' + } + end + + it 'maps log-level case-insensitive' do + component.release + + expect(java_opts).to include('-Djma.log_level=DEBUG') + end + + end + + context do + let(:configuration) do + { + 'log_level' => 'WARN' + } + end + + let(:version) { '0.1.0' } + + it 'maps log-level WARN to WARNING' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ + 'java-memory-assistant-0.1.0.jar') + + expect(java_opts).to include('-Djma.enabled=true') + expect(java_opts).to include('-Djma.log_level=WARNING') + end + + end + + context do + let(:configuration) do + { + 'log_level' => 'INFO' + } + end + + let(:version) { '0.1.0' } + + it 'maps log-level INFO to INFO' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ + 'java-memory-assistant-0.1.0.jar') + + expect(java_opts).to include('-Djma.enabled=true') + expect(java_opts).to include('-Djma.log_level=INFO') + end + + end + + context do + let(:configuration) do + { + 'log_level' => 'ERROR' + } + end + + it 'maps log-level ERROR to ERROR' do + component.release + + expect(java_opts).to include('-Djma.log_level=ERROR') + end + + end + + context do + let(:configuration) do + { + 'log_level' => 'FATAL' + } + end + + it 'maps log-level FATAL to ERROR' do + component.release + + expect(java_opts).to include('-Djma.log_level=ERROR') + end + + end + + context do + + let(:configuration) do + {} + end + + it 'falls back on JBP log_level when no log_level specified via configuration', + :enable_log_file, log_level: 'WARN' do + component.release + + expect(java_opts).to include('-Djma.log_level=WARNING') + end + + end + + context do + let(:configuration) do + { + 'log_level' => 'ciao' + } + end + + it 'fails if log_level is not recognized' do + expect { component.release }.to raise_exception 'Invalid value of the \'log_level\'' \ + ' property: \'ciao\'' + end + + end + +end diff --git a/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb new file mode 100644 index 0000000000..9aeb77a524 --- /dev/null +++ b/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb @@ -0,0 +1,97 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'application_helper' +require 'component_helper' +require 'java_buildpack/framework/java_memory_assistant/clean_up' + +describe JavaBuildpack::Framework::JavaMemoryAssistantCleanUp do + include_context 'application_helper' + include_context 'component_helper' + + let(:version) { '1.2.3' } + + context do + + let(:configuration) do + { + 'max_dump_count' => 1 + } + end + + it 'downloads and unpacks the cleanup command', + cache_fixture: 'stub-java-memory-assistant-cleanup.zip' do + + component.compile + + expect(sandbox + 'cleanup').to exist + end + + end + + context do + + let(:configuration) do + { + 'max_dump_count' => 1 + } + end + + it 'configures clean up' do + component.release + + expect(java_opts).to include('-Djma.command.interpreter=') + expect(java_opts).to include('-Djma.execute.before=$PWD/.java-buildpack/java_memory_assistant_clean_up/' \ + 'cleanup') + end + + end + + context do + + let(:configuration) do + { + 'max_dump_count' => 0 + } + end + + it 'does not configure clean up when max_dump_count is zero' do + component.release + + expect(java_opts).not_to include('-Djma.command.interpreter=') + expect(java_opts).not_to include('-Djma.execute.before=$PWD/.java-buildpack/java_memory_assistant_clean_up/' \ + 'cleanup') + end + + end + + context do + + let(:configuration) do + {} + end + + it 'does not configure clean up when max_dump_count is not set' do + component.release + + expect(java_opts).not_to include('-Djma.command.interpreter=') + expect(java_opts).not_to include('-Djma.execute.before=$PWD/.java-buildpack/java_memory_assistant_clean_up/' \ + 'cleanup') + end + + end + +end diff --git a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb new file mode 100644 index 0000000000..992b4eafd0 --- /dev/null +++ b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb @@ -0,0 +1,131 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'application_helper' +require 'component_helper' +require 'logging_helper' +require 'java_buildpack/framework/java_memory_assistant/heap_dump_folder' + +describe JavaBuildpack::Framework::JavaMemoryAssistantHeapDumpFolder do + include_context 'application_helper' + include_context 'component_helper' + include_context 'logging_helper' + + let(:logger) { described_class.instance.get_logger String } + + context do + let(:vcap_application) do + { + 'space_name' => '1234567890', + 'space_id' => '0987654321', + 'application_name' => 'abcdefghi', + 'application_id' => 'ihgfedcba' + } + end + + let(:configuration) do + { + 'heap_dump_folder' => nil + } + end + + it 'uses the default for \'jma.heap_dump_folder\' if no value is specified', :enable_log_file, log_level: 'INFO' do + + component.release + + expect(java_opts).to include('-Djma.heap_dump_folder="1234567890-09876543/abcdefghi-ihgfedcb"') + expect(environment_variables).to include('JMA_HEAP_DUMP_FOLDER=1234567890-09876543/abcdefghi-ihgfedcb') + + expect(log_contents).to match(%r{Heap dumps will be stored under '1234567890-09876543/abcdefghi-ihgfedcb'}) + end + + end + + context do + let(:configuration) do + { + 'heap_dump_folder' => 'test/folder' + } + end + + it 'adds \'jma.heap_dump_folder\' with verbatim value', :enable_log_file, log_level: 'INFO' do + + component.release + + expect(java_opts).to include('-Djma.heap_dump_folder="test/folder"') + expect(environment_variables).to include('JMA_HEAP_DUMP_FOLDER=test/folder') + + expect(log_contents).to match(%r{Heap dumps will be stored under \'test/folder\'}) + end + + end + + context do + let(:configuration) do + { + 'heap_dump_folder' => 'test/folder' + } + end + + before do + allow(services).to receive(:find_service).with('heap-dump') + .and_return('volume_mounts' => + [ + { + 'container_dir' => '/my_volume', + 'mode' => 'rw' + } + ]) + end + + it 'adds \'jma.heap_dump_folder\' with volume container_dir as path root', :enable_log_file, log_level: 'INFO' do + + component.release + + expect(java_opts).to include('-Djma.heap_dump_folder="/my_volume/test/folder"') + expect(environment_variables).to include('JMA_HEAP_DUMP_FOLDER=/my_volume/test/folder') + + expect(log_contents).to match(%r{Heap dumps will be stored under \'/my_volume/test/folder\'}) + end + + end + + context do + let(:configuration) do + { + 'heap_dump_folder' => 'test/folder' + } + end + + before do + allow(services).to receive(:find_service).with('heap-dump') + .and_return('volume_mounts' => + [ + { + 'container_dir' => '/my_volume', + 'mode' => 'r' + } + ]) + end + + it 'fails if volume does not have write mode active', :enable_log_file, log_level: 'DEBUG' do + expect { component.release } .to raise_error 'Volume mounted under \'/my_volume\' not in write mode' + expect(log_contents).not_to match(/Heap dumps will be stored under/) + end + + end + +end diff --git a/spec/java_buildpack/framework/java_memory_assistant_spec.rb b/spec/java_buildpack/framework/java_memory_assistant_spec.rb new file mode 100644 index 0000000000..32f73e3933 --- /dev/null +++ b/spec/java_buildpack/framework/java_memory_assistant_spec.rb @@ -0,0 +1,73 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'application_helper' +require 'component_helper' +require 'java_buildpack/framework/java_memory_assistant' +require 'java_buildpack/framework/java_memory_assistant/agent' +require 'java_buildpack/framework/java_memory_assistant/clean_up' +require 'java_buildpack/framework/java_memory_assistant/heap_dump_folder' + +describe JavaBuildpack::Framework::JavaMemoryAssistant do + include_context 'component_helper' + + let(:component) { StubJavaMemoryAssistant.new context } + + context do + + let(:configuration) do + { + 'enabled' => false + } + end + + it 'does not activate submodules if it is disabled in the configuration' do + expect(component.detect).not_to be + end + + end + + context do + + let(:configuration) do + { 'enabled' => true, + 'agent' => agent_configuration, + 'clean_up' => clean_up_configuration } + end + + let(:agent_configuration) { instance_double('agent_configuration') } + + let(:clean_up_configuration) { instance_double('clean_up_configuration') } + + it 'creates submodules' do + allow(JavaBuildpack::Framework::JavaMemoryAssistantAgent) + .to receive(:new).with(sub_configuration_context(agent_configuration)) + allow(JavaBuildpack::Framework::JavaMemoryAssistantHeapDumpFolder) + .to receive(:new).with(sub_configuration_context(agent_configuration)) + allow(JavaBuildpack::Framework::JavaMemoryAssistantCleanUp) + .to receive(:new).with(sub_configuration_context(clean_up_configuration)) + + component.sub_components context + end + end + +end + +class StubJavaMemoryAssistant < JavaBuildpack::Framework::JavaMemoryAssistant + + public :command, :sub_components, :supports? + +end From f5efa6ec235828eeaddda95ffc94defe261ef899 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 5 Jul 2017 09:54:30 +0100 Subject: [PATCH 312/812] Polishing This change polishes up the contribution to meet our coding standards. [resolves #436] --- docs/framework-java_memory_assistant.md | 8 ++- .../framework/java_memory_assistant.rb | 4 +- .../framework/java_memory_assistant/agent.rb | 67 +++++++++---------- .../java_memory_assistant/clean_up.rb | 11 ++- .../java_memory_assistant/heap_dump_folder.rb | 4 +- .../heap_dump_folder_spec.rb | 28 ++++---- 6 files changed, 58 insertions(+), 64 deletions(-) diff --git a/docs/framework-java_memory_assistant.md b/docs/framework-java_memory_assistant.md index 7e2ad936de..9b60357835 100644 --- a/docs/framework-java_memory_assistant.md +++ b/docs/framework-java_memory_assistant.md @@ -15,7 +15,7 @@ Tags are printed to standard output by the buildpack detect script. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. -The framework can be configured by modifying the [``config/java_memory_assistant.yml``][] file in the buildpack fork. +The framework can be configured by modifying the [`config/java_memory_assistant.yml`][] file in the buildpack fork. | Name | Description | ---- | ----------- @@ -47,7 +47,7 @@ The timestamp pattern `%ts:yyyyMMdd'T'mmssSSSZ%` is equivalent to the `%FT%T%z` | Survivor | `survivor` | | Old Generation | `old_gen` | -The default values can be found in the [``config/java_memory_assistant.yml``][] file. +The default values can be found in the [`config/java_memory_assistant.yml`][] file. ### Examples @@ -112,4 +112,6 @@ To prevent heap dumps from "going down" with the container, you should consider #### Container-mounted volumes -If you are using a filesystem service that mounts persistent volumes to the container, it is enough to name one of the volume services `heap-dump` or tag one volume with `heap-dump`, and the path specified as the `heap_dump_folder` configuration will be resolved against `/-/-`. \ No newline at end of file +If you are using a filesystem service that mounts persistent volumes to the container, it is enough to name one of the volume services `heap-dump` or tag one volume with `heap-dump`, and the path specified as the `heap_dump_folder` configuration will be resolved against `/-/-`. + +[`config/java_memory_assistant.yml`]: ../config/java_memory_assistant.yml diff --git a/lib/java_buildpack/framework/java_memory_assistant.rb b/lib/java_buildpack/framework/java_memory_assistant.rb index 1e5522ad73..79f491e01b 100644 --- a/lib/java_buildpack/framework/java_memory_assistant.rb +++ b/lib/java_buildpack/framework/java_memory_assistant.rb @@ -28,9 +28,7 @@ class JavaMemoryAssistant < JavaBuildpack::Component::ModularComponent protected # (see JavaBuildpack::Component::ModularComponent#command) - def command - # Nothing to do here, the agent is initialized via java opts - end + def command; end # (see JavaBuildpack::Component::ModularComponent#sub_components) def sub_components(context) diff --git a/lib/java_buildpack/framework/java_memory_assistant/agent.rb b/lib/java_buildpack/framework/java_memory_assistant/agent.rb index 363944d038..7cbfecda39 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/agent.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/agent.rb @@ -34,67 +34,64 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.java_opts.add_javaagent @droplet.sandbox + jar_name - - @droplet.java_opts.add_system_property 'jma.enabled', 'true' - @droplet.java_opts.add_system_property 'jma.heap_dump_name', %("#{name_pattern}") + @droplet.java_opts + .add_javaagent(@droplet.sandbox + jar_name) + .add_system_property('jma.enabled', 'true') + .add_system_property('jma.heap_dump_name', %("#{name_pattern}")) + .add_system_property 'jma.log_level', normalized_log_level add_system_prop_if_config_present 'check_interval', 'jma.check_interval' add_system_prop_if_config_present 'max_frequency', 'jma.max_frequency' - @droplet.java_opts.add_system_property 'jma.log_level', log_level + return unless @configuration.key?('thresholds') - (@configuration['thresholds'] || {}).each do |key, value| + @configuration['thresholds'].each do |key, value| @droplet.java_opts.add_system_property "jma.thresholds.#{key}", value.to_s end end protected - def supports? - true - end - # (see JavaBuildpack::Component::VersionedDependencyComponent#jar_name) def jar_name "java-memory-assistant-#{@version}.jar" end - private - - def name_pattern - # Double escaping quotes of doom. Nothing less would work. - %q(%env:CF_INSTANCE_INDEX%-%ts:yyyy-MM-dd'"'"'T'"'"'mm'"'"':'"'"'ss'"'"':'"'"'SSSZ%-) \ - '%env:CF_INSTANCE_GUID[,8]%.hprof' + def supports? + true end - def add_system_prop_if_config_present(config_entry, system_property_name, quote_value = false) - return unless @configuration[config_entry] + private + + LOG_LEVEL_MAPPING = { + 'DEBUG' => 'DEBUG', + 'WARN' => 'WARNING', + 'INFO' => 'INFO', + 'ERROR' => 'ERROR', + 'FATAL' => 'ERROR' + }.freeze - config_value = @configuration[config_entry] - config_value = '"' + config_value + '"' if quote_value + private_constant :LOG_LEVEL_MAPPING - @droplet.java_opts.add_system_property(system_property_name, config_value) + def add_system_prop_if_config_present(config_entry, system_property_name) + return unless @configuration.key?(config_entry) + @droplet.java_opts.add_system_property(system_property_name, @configuration[config_entry]) end def log_level - actual_log_level = @configuration['log_level'] || ENV['JBP_LOG_LEVEL'] || 'ERROR' - - mapped_log_level = log_level_mapping[actual_log_level.upcase] - - raise "Invalid value of the 'log_level' property: '#{actual_log_level}'" unless mapped_log_level + @configuration['log_level'] || ENV['JBP_LOG_LEVEL'] || 'ERROR' + end - mapped_log_level + def normalized_log_level + normalized_log_level = LOG_LEVEL_MAPPING[log_level.upcase] + raise "Invalid value of the 'log_level' property: '#{log_level}'" unless normalized_log_level + normalized_log_level end - def log_level_mapping - { - 'DEBUG' => 'DEBUG', - 'WARN' => 'WARNING', - 'INFO' => 'INFO', - 'ERROR' => 'ERROR', - 'FATAL' => 'ERROR' - } + def name_pattern + # Double escaping quotes of doom. Nothing less would work. + %q(%env:CF_INSTANCE_INDEX%-%ts:yyyy-MM-dd'"'"'T'"'"'mm'"'"':'"'"'ss'"'"':'"'"'SSSZ%-) \ + '%env:CF_INSTANCE_GUID[,8]%.hprof' end end diff --git a/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb b/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb index 7bd24853aa..c7d8a01e15 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb @@ -28,19 +28,18 @@ def compile return unless supports? download_zip false - - @droplet.copy_resources end # (see JavaBuildpack::Component::BaseComponent#release) def release return unless supports? - environment_variables = @droplet.environment_variables - environment_variables.add_environment_variable 'JMA_MAX_DUMP_COUNT', @configuration['max_dump_count'].to_s + @droplet.environment_variables + .add_environment_variable 'JMA_MAX_DUMP_COUNT', @configuration['max_dump_count'].to_s - @droplet.java_opts.add_system_property('jma.command.interpreter', '') - @droplet.java_opts.add_system_property('jma.execute.before', @droplet.sandbox + 'cleanup') + @droplet.java_opts + .add_system_property('jma.command.interpreter', '') + .add_system_property('jma.execute.before', @droplet.sandbox + 'cleanup') end protected diff --git a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb index 1a2316d4c8..2e305fefab 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb @@ -38,9 +38,7 @@ def detect end # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - # Nothing to do - end + def compile; end # (see JavaBuildpack::Component::BaseComponent#release) def release diff --git a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb index 992b4eafd0..36613185ac 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb @@ -82,13 +82,13 @@ before do allow(services).to receive(:find_service).with('heap-dump') - .and_return('volume_mounts' => - [ - { - 'container_dir' => '/my_volume', - 'mode' => 'rw' - } - ]) + .and_return('volume_mounts' => + [ + { + 'container_dir' => '/my_volume', + 'mode' => 'rw' + } + ]) end it 'adds \'jma.heap_dump_folder\' with volume container_dir as path root', :enable_log_file, log_level: 'INFO' do @@ -112,13 +112,13 @@ before do allow(services).to receive(:find_service).with('heap-dump') - .and_return('volume_mounts' => - [ - { - 'container_dir' => '/my_volume', - 'mode' => 'r' - } - ]) + .and_return('volume_mounts' => + [ + { + 'container_dir' => '/my_volume', + 'mode' => 'r' + } + ]) end it 'fails if volume does not have write mode active', :enable_log_file, log_level: 'DEBUG' do From 71e57f9fa41ba657ffcbfd239e81facb55b6a1c2 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 5 Jul 2017 09:58:11 +0100 Subject: [PATCH 313/812] Additional Documentation --- docs/framework-java_memory_assistant.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/framework-java_memory_assistant.md b/docs/framework-java_memory_assistant.md index 9b60357835..6612aab909 100644 --- a/docs/framework-java_memory_assistant.md +++ b/docs/framework-java_memory_assistant.md @@ -33,7 +33,7 @@ The heap dump filenames will be generated according to the following name patter `-%ts:yyyyMMdd'T'mmssSSSZ%-.hprof` -The timestamp pattern `%ts:yyyyMMdd'T'mmssSSSZ%` is equivalent to the `%FT%T%z` pattern of [strftime](http://www.cplusplus.com/reference/ctime/strftime/) for [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). +The timestamp pattern `%ts:yyyyMMdd'T'mmssSSSZ%` is equivalent to the `%FT%T%z` pattern of [strftime](http://www.cplusplus.com/reference/ctime/strftime/) for [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). The default naming convention matches the [`jvmkill`][] naming convention. ### Supported Memory Areas @@ -112,6 +112,7 @@ To prevent heap dumps from "going down" with the container, you should consider #### Container-mounted volumes -If you are using a filesystem service that mounts persistent volumes to the container, it is enough to name one of the volume services `heap-dump` or tag one volume with `heap-dump`, and the path specified as the `heap_dump_folder` configuration will be resolved against `/-/-`. +If you are using a filesystem service that mounts persistent volumes to the container, it is enough to name one of the volume services `heap-dump` or tag one volume with `heap-dump`, and the path specified as the `heap_dump_folder` configuration will be resolved against `/-/-`. The default directory convention matches the [`jvmkill`][] directory convention. [`config/java_memory_assistant.yml`]: ../config/java_memory_assistant.yml +[`jvmkill`]: jre-open_jdk_jre.md#jvmkill From 8ba9dd3ac91b53fb22c70485483b3d770e7e2ac9 Mon Sep 17 00:00:00 2001 From: Dmitri Gabbasov Date: Tue, 4 Jul 2017 13:48:46 +0300 Subject: [PATCH 314/812] Add Flag to Disable JRebel This change adds a flag to the JRebel configuration that allows users to explicitly disable the JRebel framework. [resolves #457] --- config/jrebel_agent.yml | 1 + docs/framework-jrebel_agent.md | 1 + lib/java_buildpack/framework/jrebel_agent.rb | 10 ++++++++-- spec/java_buildpack/framework/jrebel_agent_spec.rb | 9 +++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml index e5e0d4dd23..8f2291c6a2 100644 --- a/config/jrebel_agent.yml +++ b/config/jrebel_agent.yml @@ -17,3 +17,4 @@ --- version: 7.+ repository_root: https://dl.zeroturnaround.com/jrebel +enabled: true diff --git a/docs/framework-jrebel_agent.md b/docs/framework-jrebel_agent.md index 6b60a9f955..c1c6a5f6c8 100644 --- a/docs/framework-jrebel_agent.md +++ b/docs/framework-jrebel_agent.md @@ -25,6 +25,7 @@ The framework can be configured by modifying the [`config/jrebel_agent.yml`][] f | ---- | ----------- | `repository_root` | The URL of the JRebel repository index ([details][repositories]). | `version` | The version of JRebel to use. Candidate versions can be found in [this listing][]. +| `enabled` | Whether to activate JRebel (upon the presence of `rebel-remote.xml`) or not. [Configuration and Extension]: ../README.md#configuration-and-extension [`config/jrebel_agent.yml`]: ../config/jrebel_agent.yml diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index 9e7a4b9049..ad8ddf9b0f 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -46,8 +46,10 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - jrebel_configured?(@application.root) || jrebel_configured?(@application.root + 'WEB-INF/classes') || - jars_with_jrebel_configured?(@application.root) + enabled? && ( + jrebel_configured?(@application.root) || + jrebel_configured?(@application.root + 'WEB-INF/classes') || + jars_with_jrebel_configured?(@application.root)) end private @@ -68,6 +70,10 @@ def architecture `uname -m`.strip end + def enabled? + @configuration['enabled'].nil? || @configuration['enabled'] + end + end end diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb index db4fc51c97..c6f91b223b 100644 --- a/spec/java_buildpack/framework/jrebel_agent_spec.rb +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -39,6 +39,15 @@ expect(component.detect).to eq("jrebel-agent=#{version}") end + context do + let(:configuration) { { 'enabled' => false } } + + it 'does not detect when not enabled', + app_fixture: 'framework_jrebel_app_simple' do + expect(component.detect).to be_nil + end + end + it 'downloads the JRebel JAR and the native agent', app_fixture: 'framework_jrebel_app_simple', cache_fixture: 'stub-jrebel-archive.zip' do From 3528a3785f9819f2d12b576c3d6a0975aaa758db Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 7 Jul 2017 11:05:40 +0100 Subject: [PATCH 315/812] Improve Java Opts Coherence Previously, the way that JAVA_OPTS were handled was a bit inconsistent. First, JAVA_OPTS from the environment could be used to affect the memory calculator, but JAVA_OPTS from configuration could not due to the fact that they were assembled on the command line after the calculator had run. In addition, any changes to the environment's JAVA_OPTS would require a restage as those values were written into the command line instead of just being passed through the command stream. This change attempts to improve the consistency of how JAVA_OPTS are handled by doing two things. First, the environment's JAVA_OPTS are never processed as part of staging. Instead, a $JAVA_OPTS is appended (or not depending on configuration) to the JAVA_OPTS contributed to the buildpack. This solves the restage issue. Second, it declares the JAVA_OPTS as the very first part of the execution command, before the memory calculator. This solves the issue of ensuring that both environment and configured JAVA_OPTS are available to the memory calculator at startup. [#423][#424] --- lib/java_buildpack/buildpack.rb | 6 ++- lib/java_buildpack/container/dist_zip_like.rb | 1 - lib/java_buildpack/container/groovy.rb | 1 - lib/java_buildpack/container/java_main.rb | 2 - .../container/spring_boot_cli.rb | 1 - lib/java_buildpack/container/tomcat.rb | 1 - lib/java_buildpack/framework/java_opts.rb | 46 ++++++++----------- .../jre/open_jdk_like_memory_calculator.rb | 16 ++----- lib/java_buildpack/util/play/post22.rb | 10 +--- lib/java_buildpack/util/play/pre22.rb | 2 +- spec/java_buildpack/buildpack_spec.rb | 4 +- .../container/dist_zip_like_spec.rb | 3 +- spec/java_buildpack/container/groovy_spec.rb | 4 +- .../container/java_main_spec.rb | 12 ++--- spec/java_buildpack/container/ratpack_spec.rb | 3 +- .../container/spring_boot_cli_spec.rb | 2 +- .../container/spring_boot_spec.rb | 3 +- spec/java_buildpack/container/tomcat_spec.rb | 5 +- .../framework/java_opts_spec.rb | 45 ++---------------- .../open_jdk_like_memory_calculator_spec.rb | 31 ++----------- spec/java_buildpack/jre/open_jdk_like_spec.rb | 10 ++-- spec/java_buildpack/util/play/post22_spec.rb | 18 +------- .../util/play/pre22_dist_spec.rb | 4 +- .../util/play/pre22_staged_spec.rb | 2 +- 24 files changed, 64 insertions(+), 168 deletions(-) diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index af0803f2dc..7d6d28e84b 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -81,6 +81,8 @@ def release component_detection('framework', @frameworks, false).map(&:release) commands << container.release + + commands.insert 0, @java_opts.as_env_var command = commands.flatten.compact.join(' && ') payload = { @@ -111,6 +113,8 @@ def initialize(app_dir, application) log_environment_variables log_application_contents application + @java_opts = Component::JavaOpts.new(app_dir) + mutable_java_home = Component::MutableJavaHome.new immutable_java_home = Component::ImmutableJavaHome.new mutable_java_home, app_dir @@ -120,7 +124,7 @@ def initialize(app_dir, application) 'application' => application, 'env_vars' => Component::EnvironmentVariables.new(app_dir), 'extension_directories' => Component::ExtensionDirectories.new(app_dir), - 'java_opts' => Component::JavaOpts.new(app_dir), + 'java_opts' => @java_opts, 'security_providers' => Component::SecurityProviders.new } diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 599169b425..b331b72e2a 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -42,7 +42,6 @@ def release [ @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, - @droplet.java_opts.as_env_var, 'exec', qualify_path(start_script(root), @droplet.root) ].flatten.compact.join(' ') diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index e02189dd90..59289fa103 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -54,7 +54,6 @@ def release [ @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, - @droplet.java_opts.as_env_var, 'exec', qualify_path(@droplet.sandbox + 'bin/groovy', @droplet.root), @droplet.additional_libraries.as_classpath, diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index dd14d95383..d036905af0 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -72,8 +72,6 @@ def release def release_text(classpath) [ - @droplet.java_opts.as_env_var, - '&&', @droplet.environment_variables.as_env_vars, 'eval', 'exec', diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index 2b745b3ba3..69ffa32f29 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -49,7 +49,6 @@ def release [ @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, - @droplet.java_opts.as_env_var, 'exec', qualify_path(@droplet.sandbox + 'bin/spring', @droplet.root), 'run', diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index e81475b89a..81e8657ab6 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -39,7 +39,6 @@ def command [ @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, - @droplet.java_opts.as_env_var, 'exec', "$PWD/#{(@droplet.sandbox + 'bin/catalina.sh').relative_path_from(@droplet.root)}", 'run' diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index 6d493bed03..50e9fa3154 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -26,7 +26,7 @@ class JavaOpts < JavaBuildpack::Component::BaseComponent # (see JavaBuildpack::Component::BaseComponent#detect) def detect - supports_configuration? || supports_environment? ? JavaOpts.to_s.dash_case : nil + JavaOpts.to_s.dash_case end # (see JavaBuildpack::Component::BaseComponent#compile) @@ -34,7 +34,14 @@ def compile; end # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.java_opts.concat parsed_java_opts + configured + .shellsplit + .map { |java_opt| /(?.+?)=(?.+)/ =~ java_opt ? "#{key}=#{escape_value(value)}" : java_opt } + .each { |java_opt| @droplet.java_opts << java_opt } + + @droplet.java_opts << '$JAVA_OPTS' if from_environment? + + @droplet.java_opts.as_env_var end private @@ -43,39 +50,22 @@ def release ENVIRONMENT_PROPERTY = 'from_environment'.freeze - ENVIRONMENT_VARIABLE = 'JAVA_OPTS'.freeze - - private_constant :CONFIGURATION_PROPERTY, :ENVIRONMENT_PROPERTY, :ENVIRONMENT_VARIABLE - - def parsed_java_opts - parsed_java_opts = [] + private_constant :CONFIGURATION_PROPERTY, :ENVIRONMENT_PROPERTY - parsed_java_opts.concat @configuration[CONFIGURATION_PROPERTY].shellsplit if supports_configuration? - parsed_java_opts.concat ENV[ENVIRONMENT_VARIABLE].shellsplit if supports_environment? - - parsed_java_opts.map do |java_opt| - if /(?.+?)=(?.+)/ =~ java_opt - "#{key}=#{parse_shell_string(value)}" - else - java_opt - end - end + def configured + @configuration[CONFIGURATION_PROPERTY] || '' end - def parse_shell_string(str) + def escape_value(str) return "''" if str.empty? - str = str.dup - str.gsub!(%r{([^A-Za-z0-9_\-.,:\/@\n$\\])}, '\\\\\\1') - str.gsub!(/\n/, "'\n'") - str - end - def supports_configuration? - @configuration.key?(CONFIGURATION_PROPERTY) && !@configuration[CONFIGURATION_PROPERTY].nil? + str + .gsub(%r{([^A-Za-z0-9_\-.,:\/@\n$\\])}, '\\\\\\1') + .gsub(/\n/, "'\n'") end - def supports_environment? - @configuration[ENVIRONMENT_PROPERTY] && ENV.key?(ENVIRONMENT_VARIABLE) + def from_environment? + @configuration[ENVIRONMENT_PROPERTY] end end diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 3e79fe832d..bbb65b75dd 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -43,8 +43,7 @@ def compile memory_calculator.chmod 0o755 puts " Loaded Classes: #{class_count @configuration}, " \ - "Threads: #{stack_threads @configuration}, " \ - "JAVA_OPTS: '#{java_opts}'" + "Threads: #{stack_threads @configuration}" end end @@ -53,13 +52,12 @@ def compile # @return [String] the memory calculation command def memory_calculation_command "CALCULATED_MEMORY=$(#{memory_calculation_string(@droplet.root)}) && " \ - 'echo JVM Memory Configuration: $CALCULATED_MEMORY' + 'echo JVM Memory Configuration: $CALCULATED_MEMORY && ' \ + 'JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"' end # (see JavaBuildpack::Component::BaseComponent#release) - def release - @droplet.java_opts.add_preformatted_options '$CALCULATED_MEMORY' - end + def release; end protected @@ -85,10 +83,6 @@ def class_count(configuration) configuration['class_count'] || (0.35 * actual_class_count(root)).ceil end - def java_opts - ENV['JAVA_OPTS'] - end - def memory_calculator @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{@version}" end @@ -104,7 +98,7 @@ def memory_calculation_string(relative_path) memory_calculation_string << "-stackThreads=#{stack_threads @configuration}" memory_calculation_string << "-loadedClasses=#{class_count @configuration}" memory_calculation_string << "-poolType=#{pool_type}" - memory_calculation_string << "-vmOptions='#{java_opts}'" if java_opts + memory_calculation_string << '-vmOptions="$JAVA_OPTS"' memory_calculation_string.join(' ') end diff --git a/lib/java_buildpack/util/play/post22.rb b/lib/java_buildpack/util/play/post22.rb index 723e2e0c76..fec4096ab3 100644 --- a/lib/java_buildpack/util/play/post22.rb +++ b/lib/java_buildpack/util/play/post22.rb @@ -39,15 +39,7 @@ def augment_classpath # (see JavaBuildpack::Util::Play::Base#java_opts) def java_opts - java_opts = @droplet.java_opts - - java_opts.each do |option| - next unless option.shellsplit.length > 1 && !bash_expression?(option) - - raise "Invalid Java option contains more than one option: '#{option}'" - end - - java_opts.map { |option| option == '$CALCULATED_MEMORY' ? '${CALCULATED_MEMORY//-/-J-}' : "-J#{option}" } + '${JAVA_OPTS//-/-J-}' end # (see JavaBuildpack::Util::Play::Base#lib_dir) diff --git a/lib/java_buildpack/util/play/pre22.rb b/lib/java_buildpack/util/play/pre22.rb index 56f7d01a36..9dba3ed6a7 100644 --- a/lib/java_buildpack/util/play/pre22.rb +++ b/lib/java_buildpack/util/play/pre22.rb @@ -26,7 +26,7 @@ class Pre22 < Base # (see JavaBuildpack::Util::Play::Base#java_opts) def java_opts - @droplet.java_opts + '$JAVA_OPTS' end # (see JavaBuildpack::Util::Play::Base#start_script) diff --git a/spec/java_buildpack/buildpack_spec.rb b/spec/java_buildpack/buildpack_spec.rb index 4d8b80a7dd..ed3cf61b88 100644 --- a/spec/java_buildpack/buildpack_spec.rb +++ b/spec/java_buildpack/buildpack_spec.rb @@ -129,8 +129,8 @@ expect(buildpack.release) .to eq({ 'addons' => [], 'config_vars' => {}, - 'default_process_types' => { 'web' => 'test-command', - 'task' => 'test-command' } }.to_yaml) + 'default_process_types' => { 'web' => 'JAVA_OPTS="" && test-command', + 'task' => 'JAVA_OPTS="" && test-command' } }.to_yaml) end it 'loads configuration file matching JRE class name' do diff --git a/spec/java_buildpack/container/dist_zip_like_spec.rb b/spec/java_buildpack/container/dist_zip_like_spec.rb index 3d2a1657f3..96856a0601 100644 --- a/spec/java_buildpack/container/dist_zip_like_spec.rb +++ b/spec/java_buildpack/container/dist_zip_like_spec.rb @@ -50,8 +50,7 @@ it 'returns command', app_fixture: 'container_dist_zip' do - expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} " \ - 'JAVA_OPTS="test-opt-2 test-opt-1" exec $PWD/bin/application') + expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} exec $PWD/bin/application") end end diff --git a/spec/java_buildpack/container/groovy_spec.rb b/spec/java_buildpack/container/groovy_spec.rb index e1f45ae2bc..419cf335ff 100644 --- a/spec/java_buildpack/container/groovy_spec.rb +++ b/spec/java_buildpack/container/groovy_spec.rb @@ -90,7 +90,7 @@ it 'returns command', app_fixture: 'container_groovy_main_method' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} exec " \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} exec " \ '$PWD/.java-buildpack/groovy/bin/groovy -cp $PWD/.additional_libs/test-jar-1.jar:' \ '$PWD/.additional_libs/test-jar-2.jar Application.groovy Alpha.groovy ' \ 'directory/Beta.groovy invalid.groovy') @@ -99,7 +99,7 @@ it 'returns command with included JARs', app_fixture: 'container_groovy_with_jars' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} exec " \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} exec " \ '$PWD/.java-buildpack/groovy/bin/groovy -cp $PWD/.additional_libs/test-jar-1.jar:' \ '$PWD/.additional_libs/test-jar-2.jar:$PWD/Alpha.jar:$PWD/directory/Beta.jar ' \ 'Application.groovy invalid.groovy') diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index 383a271a12..e7af6291c9 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -76,7 +76,7 @@ it 'returns command' do - expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ + expect(component.release).to eq('test-var-2 test-var-1 ' \ "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ '.additional_libs/test-jar-2.jar test-java-main-class') @@ -86,7 +86,7 @@ it 'returns additional classpath entries when Class-Path is specified', app_fixture: 'container_main' do - expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ + expect(component.release).to eq('test-var-2 test-var-1 ' \ "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ '.additional_libs/test-jar-2.jar:$PWD/alpha.jar:$PWD/bravo.jar:$PWD/' \ @@ -98,7 +98,7 @@ it 'returns command line arguments when they are specified' do - expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 ' \ + expect(component.release).to eq('test-var-2 test-var-1 ' \ "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ 'test-jar-2.jar test-java-main-class some arguments') @@ -108,7 +108,7 @@ it 'releases Spring boot applications with a JarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_jar_launcher' do - expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/. org.springframework.boot.loader.JarLauncher') end @@ -116,7 +116,7 @@ it 'releases Spring boot applications with a WarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_war_launcher' do - expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/. org.springframework.boot.loader.WarLauncher') end @@ -124,7 +124,7 @@ it 'releases Spring boot applications with a PropertiesLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_properties_launcher' do - expect(component.release).to eq('JAVA_OPTS="test-opt-2 test-opt-1" && test-var-2 test-var-1 SERVER_PORT=$PORT ' \ + expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ '-cp $PWD/. org.springframework.boot.loader.PropertiesLauncher') end diff --git a/spec/java_buildpack/container/ratpack_spec.rb b/spec/java_buildpack/container/ratpack_spec.rb index 67d12527c7..bcbf36be4e 100644 --- a/spec/java_buildpack/container/ratpack_spec.rb +++ b/spec/java_buildpack/container/ratpack_spec.rb @@ -68,8 +68,7 @@ it 'returns command', app_fixture: 'container_ratpack_staged' do - expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 " \ - 'test-opt-1" exec $PWD/bin/application') + expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} exec $PWD/bin/application") end end diff --git a/spec/java_buildpack/container/spring_boot_cli_spec.rb b/spec/java_buildpack/container/spring_boot_cli_spec.rb index f31eed64e4..b4059a8453 100644 --- a/spec/java_buildpack/container/spring_boot_cli_spec.rb +++ b/spec/java_buildpack/container/spring_boot_cli_spec.rb @@ -92,7 +92,7 @@ it 'returns command', app_fixture: 'container_spring_boot_cli_valid_app' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} JAVA_OPTS=#{java_opts_str} " \ + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} " \ 'exec $PWD/.java-buildpack/spring_boot_cli/bin/spring run ' \ '-cp $PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/test-jar-2.jar ' \ 'directory/pogo_4.groovy invalid.groovy pogo_1.groovy pogo_2.groovy pogo_3.groovy') diff --git a/spec/java_buildpack/container/spring_boot_spec.rb b/spec/java_buildpack/container/spring_boot_spec.rb index 018253d7f0..8ecd6e8ab3 100644 --- a/spec/java_buildpack/container/spring_boot_spec.rb +++ b/spec/java_buildpack/container/spring_boot_spec.rb @@ -68,8 +68,7 @@ it 'returns command', app_fixture: 'container_spring_boot_staged' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} " \ - "JAVA_OPTS=#{java_opts_str} exec $PWD/bin/application") + expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} exec $PWD/bin/application") end def env_vars_str diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index ee65087d6c..a6756ed9c9 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -85,9 +85,8 @@ end it 'returns command' do - expect(component.command).to eq("test-var-2 test-var-1 #{java_home.as_env_var} JAVA_OPTS=\"test-opt-2 " \ - 'test-opt-1 -Dhttp.port=$PORT" exec $PWD/.java-buildpack/tomcat/bin/catalina.sh' \ - ' run') + expect(component.command).to eq("test-var-2 test-var-1 #{java_home.as_env_var} exec " \ + '$PWD/.java-buildpack/tomcat/bin/catalina.sh run') end context do diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index bf98c8f453..bb2a324a19 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -37,26 +37,6 @@ end end - context do - let(:environment) { { 'JAVA_OPTS' => '-Dalpha=bravo' } } - - it 'does not detect with ENV and without from_environment configuration' do - expect(component.detect).to be_nil - end - end - - context do - let(:configuration) { { 'java_opts' => nil } } - - it 'does not detect with nil java_opts configuration' do - expect(component.detect).to be_nil - end - end - - it 'does not detect without java_opts configuration' do - expect(component.detect).to be_nil - end - context do let(:configuration) do { 'java_opts' => '-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=y ' \ @@ -94,16 +74,6 @@ end end - context do - let(:configuration) { { 'from_environment' => true } } - let(:environment) { { 'JAVA_OPTS' => '-Dtest=$dollar\\\slash' } } - - it 'does not escape the shell variable character from environment' do - component.release - expect(java_opts).to include('-Dtest=$dollar\slash') - end - end - context do let(:configuration) do { 'java_opts' => '-Dtest=something.\\\$dollar.\\\\\\\slash' } @@ -128,21 +98,16 @@ context do let(:configuration) { { 'from_environment' => true } } - let(:environment) { { 'JAVA_OPTS' => '-Dalpha=bravo' } } - it 'includes values specified in ENV[JAVA_OPTS]' do + it 'includes $JAVA_OPTS with from_environment' do component.release - expect(java_opts).to include('-Dalpha=bravo') + expect(java_opts).to include('$JAVA_OPTS') end end - context do - let(:environment) { { 'JAVA_OPTS' => '-Dalpha=bravo' } } - - it 'does not include values specified in ENV[JAVA_OPTS] without from_environment' do - component.release - expect(java_opts).not_to include('-Dalpha=bravo') - end + it 'does not include $JAVA_OPTS without from_environment' do + component.release + expect(java_opts).not_to include('$JAVA_OPTS') end end diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 55a6a1cb6b..3b59d4b31b 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -75,13 +75,7 @@ end - it 'adds $CALCULATED_MEMORY to the JAVA_OPTS' do - component.release - - expect(java_opts).to include('$CALCULATED_MEMORY') - end - - it 'creates memory calculation command without vm options specified', + it 'creates memory calculation command', app_fixture: 'jre_memory_calculator_application' do java_home.version = version_8 @@ -90,27 +84,8 @@ expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ - '-loadedClasses=2 -poolType=metaspace) && echo JVM Memory Configuration: ' \ - '$CALCULATED_MEMORY') - end - - context do - - let(:environment) { { 'JAVA_OPTS' => '-Dalpha=bravo' } } - - it 'creates memory calculation command with vm options specified', - app_fixture: 'jre_memory_calculator_application' do - - java_home.version = version_8 - - command = component.memory_calculation_command - - expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ - 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ - '-loadedClasses=2 -poolType=metaspace -vmOptions=\'-Dalpha=bravo\') && echo JVM Memory ' \ - 'Configuration: $CALCULATED_MEMORY') - end - + '-loadedClasses=2 -poolType=metaspace -vmOptions="$JAVA_OPTS") && echo JVM Memory ' \ + 'Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') end end diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index a90e781777..399b50cf6a 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -68,8 +68,9 @@ java_home.version = version_7 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ - ' -stackThreads=200 -loadedClasses=0 -poolType=permgen) && echo JVM Memory ' \ - 'Configuration: $CALCULATED_MEMORY') + ' -stackThreads=200 -loadedClasses=0 -poolType=permgen -vmOptions="$JAVA_OPTS")' \ + ' && echo JVM Memory Configuration: $CALCULATED_MEMORY && ' \ + 'JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') end @@ -77,8 +78,9 @@ java_home.version = version_8 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ - ' -stackThreads=200 -loadedClasses=0 -poolType=metaspace) && echo JVM Memory ' \ - 'Configuration: $CALCULATED_MEMORY') + ' -stackThreads=200 -loadedClasses=0 -poolType=metaspace -vmOptions="$JAVA_OPTS")' \ + ' && echo JVM Memory Configuration: $CALCULATED_MEMORY && ' \ + 'JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') end diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index dd4bba51f3..4bf4bf8ca5 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -47,23 +47,7 @@ it 'returns command' do expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ - "#{java_home.as_env_var} exec $PWD/bin/play-application -Jtest-opt-2 -Jtest-opt-1 -J-Dhttp.port=$PORT") - end - - context do - let(:java_opts) { super() << '-Xmx30m -Xms30m' } - - it 'does not allow multiple options in a single JAVA_OPTS array entry' do - expect { play_app.release }.to raise_error(/Invalid Java option contains more than one option/) - end - end - - context do - let(:java_opts) { super() << '$CALCULATED_MEMORY' } - - it 'does wraps the output of CALCULATED_MEMORY correctly' do - expect(play_app.release).to include('${CALCULATED_MEMORY//-/-J-}') - end + "#{java_home.as_env_var} exec $PWD/bin/play-application ${JAVA_OPTS//-/-J-}") end context do diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index 8c59eb744e..22494c3c57 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -103,7 +103,7 @@ it 'returns command' do expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ - "#{java_home.as_env_var} exec $PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT") + "#{java_home.as_env_var} exec $PWD/application-root/start $JAVA_OPTS") end end @@ -124,7 +124,7 @@ it 'returns command' do expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ - "#{java_home.as_env_var} exec $PWD/application-root/start test-opt-2 test-opt-1 -Dhttp.port=$PORT") + "#{java_home.as_env_var} exec $PWD/application-root/start $JAVA_OPTS") end end diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index 743a9b52da..e7454e65ac 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -103,7 +103,7 @@ it 'returns command' do expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ - "#{java_home.as_env_var} exec $PWD/start test-opt-2 test-opt-1 -Dhttp.port=$PORT") + "#{java_home.as_env_var} exec $PWD/start $JAVA_OPTS") end end From f59f85c3b8735ab269e58b93574007b7b6f025e3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 7 Jul 2017 12:20:42 +0100 Subject: [PATCH 316/812] Bug Fixing Apparently I wasn't nearly as clever as I'd thought and my removal of JAVA_OPTS was a bit too aggressive. This change cleans things up so that all containers will work. --- lib/java_buildpack/container/dist_zip_like.rb | 2 ++ lib/java_buildpack/container/groovy.rb | 1 + lib/java_buildpack/container/spring_boot_cli.rb | 4 +++- lib/java_buildpack/container/tomcat.rb | 1 + spec/java_buildpack/container/dist_zip_like_spec.rb | 3 ++- spec/java_buildpack/container/groovy_spec.rb | 12 ++---------- spec/java_buildpack/container/ratpack_spec.rb | 3 ++- spec/java_buildpack/container/tomcat_spec.rb | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index b331b72e2a..deb29d8a0a 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -39,6 +39,8 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release + @droplet.environment_variables.add_environment_variable 'JAVA_OPTS', '$JAVA_OPTS' + [ @droplet.environment_variables.as_env_vars, @droplet.java_home.as_env_var, diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index 59289fa103..dbb3147f9f 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -49,6 +49,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release + @droplet.environment_variables.add_environment_variable 'JAVA_OPTS', '$JAVA_OPTS' add_libs [ diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index 69ffa32f29..cbc8a5487a 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -44,7 +44,9 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.environment_variables.add_environment_variable 'SERVER_PORT', '$PORT' + @droplet.environment_variables + .add_environment_variable('JAVA_OPTS', '$JAVA_OPTS') + .add_environment_variable('SERVER_PORT', '$PORT') [ @droplet.environment_variables.as_env_vars, diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 81e8657ab6..395f04cae9 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -34,6 +34,7 @@ class Tomcat < JavaBuildpack::Component::ModularComponent # (see JavaBuildpack::Component::ModularComponent#command) def command + @droplet.environment_variables.add_environment_variable 'JAVA_OPTS', '$JAVA_OPTS' @droplet.java_opts.add_system_property 'http.port', '$PORT' [ diff --git a/spec/java_buildpack/container/dist_zip_like_spec.rb b/spec/java_buildpack/container/dist_zip_like_spec.rb index 96856a0601..498bb3bcf7 100644 --- a/spec/java_buildpack/container/dist_zip_like_spec.rb +++ b/spec/java_buildpack/container/dist_zip_like_spec.rb @@ -50,7 +50,8 @@ it 'returns command', app_fixture: 'container_dist_zip' do - expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} exec $PWD/bin/application") + expect(component.release).to eq("test-var-2 test-var-1 JAVA_OPTS=$JAVA_OPTS #{java_home.as_env_var} exec " \ + '$PWD/bin/application') end end diff --git a/spec/java_buildpack/container/groovy_spec.rb b/spec/java_buildpack/container/groovy_spec.rb index 419cf335ff..8068c1a091 100644 --- a/spec/java_buildpack/container/groovy_spec.rb +++ b/spec/java_buildpack/container/groovy_spec.rb @@ -90,7 +90,7 @@ it 'returns command', app_fixture: 'container_groovy_main_method' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} exec " \ + expect(component.release).to eq("test-var-2 test-var-1 JAVA_OPTS=$JAVA_OPTS #{java_home.as_env_var} exec " \ '$PWD/.java-buildpack/groovy/bin/groovy -cp $PWD/.additional_libs/test-jar-1.jar:' \ '$PWD/.additional_libs/test-jar-2.jar Application.groovy Alpha.groovy ' \ 'directory/Beta.groovy invalid.groovy') @@ -99,18 +99,10 @@ it 'returns command with included JARs', app_fixture: 'container_groovy_with_jars' do - expect(component.release).to eq("#{env_vars_str} #{java_home.as_env_var} exec " \ + expect(component.release).to eq("test-var-2 test-var-1 JAVA_OPTS=$JAVA_OPTS #{java_home.as_env_var} exec " \ '$PWD/.java-buildpack/groovy/bin/groovy -cp $PWD/.additional_libs/test-jar-1.jar:' \ '$PWD/.additional_libs/test-jar-2.jar:$PWD/Alpha.jar:$PWD/directory/Beta.jar ' \ 'Application.groovy invalid.groovy') end - def env_vars_str - environment_variables.join(' ') - end - - def java_opts_str - "\"#{java_opts.join(' ')}\"" - end - end diff --git a/spec/java_buildpack/container/ratpack_spec.rb b/spec/java_buildpack/container/ratpack_spec.rb index bcbf36be4e..bec5e54178 100644 --- a/spec/java_buildpack/container/ratpack_spec.rb +++ b/spec/java_buildpack/container/ratpack_spec.rb @@ -68,7 +68,8 @@ it 'returns command', app_fixture: 'container_ratpack_staged' do - expect(component.release).to eq("test-var-2 test-var-1 #{java_home.as_env_var} exec $PWD/bin/application") + expect(component.release).to eq("test-var-2 test-var-1 JAVA_OPTS=$JAVA_OPTS #{java_home.as_env_var} exec " \ + '$PWD/bin/application') end end diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index a6756ed9c9..74cd7970da 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -85,7 +85,7 @@ end it 'returns command' do - expect(component.command).to eq("test-var-2 test-var-1 #{java_home.as_env_var} exec " \ + expect(component.command).to eq("test-var-2 test-var-1 JAVA_OPTS=$JAVA_OPTS #{java_home.as_env_var} exec " \ '$PWD/.java-buildpack/tomcat/bin/catalina.sh run') end From f925bc3ff879e614277acf7b34c90d6698dc1ad5 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 17 Jul 2017 12:21:45 -0700 Subject: [PATCH 317/812] Update Java Buildpack Support This change updates the versions of the Java Buildpack Support jars (logging, access logging, and lifecycle) to the latest versions. [resolves #463] --- config/tomcat.yml | 6 +++--- resources/tomcat/conf/logging.properties | 6 +++--- resources/tomcat/conf/server.xml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index 423fc0d97d..cc4fe1c95a 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -24,13 +24,13 @@ external_configuration: version: 1.+ repository_root: lifecycle_support: - version: 2.+ + version: 3.+ repository_root: "{default.repository.root}/tomcat-lifecycle-support" logging_support: - version: 2.+ + version: 3.+ repository_root: "{default.repository.root}/tomcat-logging-support" access_logging_support: - version: 2.+ + version: 3.+ repository_root: "{default.repository.root}/tomcat-access-logging-support" access_logging: disabled redis_store: diff --git a/resources/tomcat/conf/logging.properties b/resources/tomcat/conf/logging.properties index bf5057cd0b..436597f185 100644 --- a/resources/tomcat/conf/logging.properties +++ b/resources/tomcat/conf/logging.properties @@ -14,10 +14,10 @@ # limitations under the License. # -handlers: com.gopivotal.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler -.handlers: com.gopivotal.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler +handlers: org.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler +.handlers: org.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler -com.gopivotal.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler.level: FINE +org.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler.level: FINE org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level: INFO org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level: INFO diff --git a/resources/tomcat/conf/server.xml b/resources/tomcat/conf/server.xml index 53fc1fc6f0..2bb402c45f 100644 --- a/resources/tomcat/conf/server.xml +++ b/resources/tomcat/conf/server.xml @@ -22,12 +22,12 @@ - - +
From 56d8477d74f08921baf800f64376a9f9a2b6efb4 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 17 Jul 2017 13:02:53 -0700 Subject: [PATCH 318/812] Play JAVA_OPTS Previously the Play JAVA_OPTS mapping (adding a -J before all of them) didn't work properly as it added a -J anywhere there was a -. This change fixes that problem. [resolves #460] --- lib/java_buildpack/util/play/post22.rb | 2 +- spec/java_buildpack/util/play/post22_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/util/play/post22.rb b/lib/java_buildpack/util/play/post22.rb index fec4096ab3..8b88ea4edc 100644 --- a/lib/java_buildpack/util/play/post22.rb +++ b/lib/java_buildpack/util/play/post22.rb @@ -39,7 +39,7 @@ def augment_classpath # (see JavaBuildpack::Util::Play::Base#java_opts) def java_opts - '${JAVA_OPTS//-/-J-}' + '$(for I in $JAVA_OPTS ; do echo "-J$I" ; done)' end # (see JavaBuildpack::Util::Play::Base#lib_dir) diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index 4bf4bf8ca5..895965a64d 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -47,7 +47,7 @@ it 'returns command' do expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ - "#{java_home.as_env_var} exec $PWD/bin/play-application ${JAVA_OPTS//-/-J-}") + "#{java_home.as_env_var} exec $PWD/bin/play-application $(for I in $JAVA_OPTS ; do echo \"-J$I\" ; done)") end context do From 0e5a542d0299a0020517ac8255bb0e75a7b4b413 Mon Sep 17 00:00:00 2001 From: Peter Tran Date: Wed, 24 May 2017 12:31:40 -0400 Subject: [PATCH 319/812] Pivotal Cloud Cache This change adds support for the Pivotal Cloud Cache as a Tomcat Session Manager. Binding to a Pivotal Cloud Cache service instance will cause Tomcat to use it as a session store. [resolves #437] --- config/tomcat.yml | 3 + lib/java_buildpack/container/tomcat.rb | 8 +- .../container/tomcat/tomcat_geode_store.rb | 176 ++++++++++++++++++ .../.java-buildpack/tomcat/conf/context.xml | 19 ++ .../.java-buildpack/tomcat/conf/server.xml | 34 ++++ .../WEB-INF/.gitkeep | 0 ..._tomcat_geode_store_cache_client_after.xml | 21 +++ ...ainer_tomcat_geode_store_context_after.xml | 19 ++ ...tainer_tomcat_geode_store_server_after.xml | 29 +++ spec/fixtures/stub-geode-store.tar | Bin 0 -> 444 bytes .../tomcat/tomcat_geode_store_spec.rb | 110 +++++++++++ spec/java_buildpack/container/tomcat_spec.rb | 24 ++- 12 files changed, 431 insertions(+), 12 deletions(-) create mode 100644 lib/java_buildpack/container/tomcat/tomcat_geode_store.rb create mode 100644 spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/context.xml create mode 100644 spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/server.xml create mode 100644 spec/fixtures/container_tomcat_geode_store/WEB-INF/.gitkeep create mode 100644 spec/fixtures/container_tomcat_geode_store_cache_client_after.xml create mode 100644 spec/fixtures/container_tomcat_geode_store_context_after.xml create mode 100644 spec/fixtures/container_tomcat_geode_store_server_after.xml create mode 100644 spec/fixtures/stub-geode-store.tar create mode 100644 spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb diff --git a/config/tomcat.yml b/config/tomcat.yml index cc4fe1c95a..b2bfab79c4 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -39,3 +39,6 @@ redis_store: database: 0 timeout: 2000 connection_pool_size: 2 +geode_store: + version: 0.+ + repository_root: "{default.repository.root}/geode-store" diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index e81475b89a..8138fe6864 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -15,12 +15,13 @@ require 'java_buildpack/component/modular_component' require 'java_buildpack/container' +require 'java_buildpack/container/tomcat/tomcat_access_logging_support' +require 'java_buildpack/container/tomcat/tomcat_external_configuration' +require 'java_buildpack/container/tomcat/tomcat_geode_store' require 'java_buildpack/container/tomcat/tomcat_insight_support' require 'java_buildpack/container/tomcat/tomcat_instance' -require 'java_buildpack/container/tomcat/tomcat_external_configuration' require 'java_buildpack/container/tomcat/tomcat_lifecycle_support' require 'java_buildpack/container/tomcat/tomcat_logging_support' -require 'java_buildpack/container/tomcat/tomcat_access_logging_support' require 'java_buildpack/container/tomcat/tomcat_redis_store' require 'java_buildpack/util/java_main_utils' @@ -50,9 +51,10 @@ def command def sub_components(context) components = [ TomcatInstance.new(sub_configuration_context(context, 'tomcat')), + TomcatAccessLoggingSupport.new(sub_configuration_context(context, 'access_logging_support')), + TomcatGeodeStore.new(sub_configuration_context(context, 'geode_store')), TomcatLifecycleSupport.new(sub_configuration_context(context, 'lifecycle_support')), TomcatLoggingSupport.new(sub_configuration_context(context, 'logging_support')), - TomcatAccessLoggingSupport.new(sub_configuration_context(context, 'access_logging_support')), TomcatRedisStore.new(sub_configuration_context(context, 'redis_store')), TomcatInsightSupport.new(context) ] diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb new file mode 100644 index 0000000000..b42fab975f --- /dev/null +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -0,0 +1,176 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/container' +require 'java_buildpack/container/tomcat/tomcat_utils' +require 'java_buildpack/logging/logger_factory' + +module JavaBuildpack + module Container + + # Encapsulates the detect, compile, and release functionality for Tomcat Redis support. + class TomcatGeodeStore < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Container + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + return unless supports? + download_tar(false, tomcat_lib, tar_name) + mutate_context + mutate_server + create_cache_client_xml + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + return unless supports? + credentials = @application.services.find_service(FILTER)['credentials'] + user = credentials[KEY_USERS].find { |u| u['username'] == 'cluster_operator' } + + @droplet.java_opts.add_system_property 'gemfire.security-username', 'cluster_operator' + @droplet.java_opts.add_system_property 'gemfire.security-password', user['password'] + @droplet.java_opts.add_system_property 'gemfire.security-client-auth-init', + 'io.pivotal.cloudcache.ClientAuthInitialize.create' + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, KEY_LOCATORS, KEY_USERS + end + + private + + FILTER = /session-replication/ + KEY_LOCATORS = 'locators'.freeze + KEY_USERS = 'users'.freeze + + SESSION_MANAGER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.Tomcat8DeltaSessionManager'.freeze + REGION_ATTRIBUTES_ID = 'PARTITION_REDUNDANT_HEAP_LRU'.freeze + CACHE_CLIENT_LISTENER_CLASS_NAME = + 'org.apache.geode.modules.session.catalina.ClientServerCacheLifecycleListener'.freeze + SCHEMA_URL = 'http://geode.apache.org/schema/cache'.freeze + SCHEMA_INSTANCE_URL = 'http://www.w3.org/2001/XMLSchema-instance'.freeze + SCHEMA_LOCATION = 'http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd'.freeze + LOCATOR_REGEXP = Regexp.new('([^\\[]+)\\[([^\\]]+)\\]').freeze + FUNCTION_SERVICE_CLASS_NAMES = [ + 'org.apache.geode.modules.util.CreateRegionFunction', + 'org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction', + 'org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction', + 'org.apache.geode.modules.util.RegionSizeFunction' + ].freeze + + private_constant :FILTER, :KEY_LOCATORS, :KEY_USERS, :SESSION_MANAGER_CLASS_NAME, :REGION_ATTRIBUTES_ID, + :CACHE_CLIENT_LISTENER_CLASS_NAME, :SCHEMA_URL, :SCHEMA_INSTANCE_URL, :SCHEMA_LOCATION, + :LOCATOR_REGEXP, :FUNCTION_SERVICE_CLASS_NAMES + + def add_client_cache(document) + client_cache = document.add_element 'client-cache', + 'xmlns' => SCHEMA_URL, + 'xmlns:xsi' => SCHEMA_INSTANCE_URL, + 'xsi:schemaLocation' => SCHEMA_LOCATION, + 'version' => '1.0' + + add_pool client_cache + add_function_service client_cache + end + + def add_functions(function_service) + FUNCTION_SERVICE_CLASS_NAMES.each do |function_class_name| + function = function_service.add_element 'function' + class_name = function.add_element 'class-name' + class_name.add_text(function_class_name) + end + end + + def add_function_service(client_cache) + function_service = client_cache.add_element 'function-service' + add_functions function_service + end + + def add_listener(server) + server.add_element 'Listener', + 'className' => CACHE_CLIENT_LISTENER_CLASS_NAME + end + + def add_locators(pool) + service = @application.services.find_service FILTER + service['credentials']['locators'].each do |locator| + match_info = LOCATOR_REGEXP.match(locator) + pool.add_element 'locator', + 'host' => match_info[1], + 'port' => match_info[2] + end + end + + def add_manager(context) + context.add_element 'Manager', + 'className' => SESSION_MANAGER_CLASS_NAME, + 'enableLocalCache' => 'true', + 'regionAttributesId' => REGION_ATTRIBUTES_ID + end + + def add_pool(client_cache) + pool = client_cache.add_element 'pool', + 'name' => 'sessions', + 'subscription-enabled' => 'true' + add_locators pool + end + + def cache_client_xml + 'cache-client.xml' + end + + def cache_client_xml_path + @droplet.sandbox + 'conf' + cache_client_xml + end + + def create_cache_client_xml + document = REXML::Document.new('') + add_client_cache document + write_xml cache_client_xml_path, document + end + + def mutate_context + puts ' Adding Geode-based Session Replication' + + document = read_xml context_xml + context = REXML::XPath.match(document, '/Context').first + + add_manager context + + write_xml context_xml, document + end + + def mutate_server + document = read_xml server_xml + + server = REXML::XPath.match(document, '/Server').first + + add_listener server + + write_xml server_xml, document + end + + def tar_name + "geode-store-#{@version}.tar.gz" + end + + end + + end +end diff --git a/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/context.xml b/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/context.xml new file mode 100644 index 0000000000..7f96549265 --- /dev/null +++ b/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/context.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/server.xml b/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/server.xml new file mode 100644 index 0000000000..925aa05504 --- /dev/null +++ b/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/server.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + diff --git a/spec/fixtures/container_tomcat_geode_store/WEB-INF/.gitkeep b/spec/fixtures/container_tomcat_geode_store/WEB-INF/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/container_tomcat_geode_store_cache_client_after.xml b/spec/fixtures/container_tomcat_geode_store_cache_client_after.xml new file mode 100644 index 0000000000..b68c118145 --- /dev/null +++ b/spec/fixtures/container_tomcat_geode_store_cache_client_after.xml @@ -0,0 +1,21 @@ + + + + + + + + + org.apache.geode.modules.util.CreateRegionFunction + + + org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction + + + org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction + + + org.apache.geode.modules.util.RegionSizeFunction + + + diff --git a/spec/fixtures/container_tomcat_geode_store_context_after.xml b/spec/fixtures/container_tomcat_geode_store_context_after.xml new file mode 100644 index 0000000000..412053d479 --- /dev/null +++ b/spec/fixtures/container_tomcat_geode_store_context_after.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/spec/fixtures/container_tomcat_geode_store_server_after.xml b/spec/fixtures/container_tomcat_geode_store_server_after.xml new file mode 100644 index 0000000000..56b8728e04 --- /dev/null +++ b/spec/fixtures/container_tomcat_geode_store_server_after.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + diff --git a/spec/fixtures/stub-geode-store.tar b/spec/fixtures/stub-geode-store.tar new file mode 100644 index 0000000000000000000000000000000000000000..816deb94d163df84d7f623093bba2a8fad996123 GIT binary patch literal 444 zcmb2|=3r25(TQYWzI<6b6}3+!3M4}VV0#wRUQ1LBt%lCJ)N%d z>_G^7$h2u~$7MRgMIL++U}U^^Mn{Q9Mn;Aw=xp`g38@y65fU}A&N8L8fA4(xKQ}2M zflVvzIfJL6;1wOFBL!#o_0`SGTX#^gYG2;`+VgY1eY|#c_lehQSC_s!^Yg4DTX>JW zjqat-pRRuVvNvK^SF7=()+ZA)G}rdXKU$S_etJfvjktKN(mJc&#H?@27xlaLB)I?i zbL{VR$&6O+D}pgRJPz%gi!7NmPBnO(VZ7Jlqr|h~Tx%uElkkv+N5v&;Ph9I>kg@sb z!~6-HF+4lwb~3bIkU4vbO(>P^&{~IIqW^BF$i8@Z^1mDN#Q(l$4*tAWoCs< z8?;n^%Ex|gcvA0L^YcE3rSR%W^Z$oxp8J1ePA7xL&-)$Ee%6chGzA)PxgFGyU|pO* S6vtVffuSPu?okE}1_l5jImZhC literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb new file mode 100644 index 0000000000..f70f763b27 --- /dev/null +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -0,0 +1,110 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/container/tomcat/tomcat_geode_store' + +describe JavaBuildpack::Container::TomcatGeodeStore do + include_context 'component_helper' + + let(:component_id) { 'tomcat' } + + let(:configuration) do + { 'database' => 'test-database', + 'timeout' => 'test-timeout', + 'connection_pool_size' => 'test-connection-pool-size' } + end + + it 'does not detect without a session-replication service' do + expect(component.detect).to be_nil + end + + context 'when there is a session-replication service' do + before do + allow(services).to receive(:one_service?).with(/session-replication/, 'locators', 'users') + .and_return(true) + allow(services).to receive(:find_service).and_return( + 'credentials' => { + 'locators' => ['some-locator[some-port]', 'some-other-locator[some-other-port]'], + 'users' => + [ + { 'password' => 'fake-password', + 'username' => 'cluster_operator' } + ] + } + ) + + end + + it 'detect with a session-replication service' do + expect(component.detect).to eq("tomcat-geode-store=#{version}") + end + + it 'copies resources', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store.tar' do + + component.compile + + expect(sandbox + 'lib/stub-geode-store/stub-jar-1.jar').to exist + expect(sandbox + 'lib/stub-geode-store/stub-jar-2.jar').to exist + end + + it 'mutates context.xml', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store.tar' do + + component.compile + + expect((sandbox + 'conf/context.xml').read) + .to eq(Pathname.new('spec/fixtures/container_tomcat_geode_store_context_after.xml').read) + end + + it 'mutates server.xml', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store.tar' do + + component.compile + + expect((sandbox + 'conf/server.xml').read) + .to eq(Pathname.new('spec/fixtures/container_tomcat_geode_store_server_after.xml').read) + end + + it 'adds a cache-client.xml', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store.tar' do + + component.compile + + expect((sandbox + 'conf/cache-client.xml').read) + .to eq(Pathname.new('spec/fixtures/container_tomcat_geode_store_cache_client_after.xml').read) + end + + it 'passes security properties to the release', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store.tar' do + + component.release + + expect(java_opts).to include( + '-Dgemfire.security-client-auth-init=io.pivotal.cloudcache.ClientAuthInitialize.create' + ) + expect(java_opts).to include('-Dgemfire.security-username=cluster_operator') + expect(java_opts).to include('-Dgemfire.security-password=fake-password') + end + + end +end diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index ee65087d6c..281fab0b86 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -17,11 +17,12 @@ require 'component_helper' require 'fileutils' require 'java_buildpack/container/tomcat' +require 'java_buildpack/container/tomcat/tomcat_access_logging_support' +require 'java_buildpack/container/tomcat/tomcat_geode_store' require 'java_buildpack/container/tomcat/tomcat_insight_support' require 'java_buildpack/container/tomcat/tomcat_instance' require 'java_buildpack/container/tomcat/tomcat_lifecycle_support' require 'java_buildpack/container/tomcat/tomcat_logging_support' -require 'java_buildpack/container/tomcat/tomcat_access_logging_support' require 'java_buildpack/container/tomcat/tomcat_redis_store' describe JavaBuildpack::Container::Tomcat do @@ -30,24 +31,27 @@ let(:component) { StubTomcat.new context } let(:configuration) do - { 'tomcat' => tomcat_configuration, + { 'access_logging_support' => access_logging_support_configuration, + 'external_configuration' => tomcat_external_configuration, + 'geode_store' => geode_store_configuration, 'lifecycle_support' => lifecycle_support_configuration, 'logging_support' => logging_support_configuration, - 'access_logging_support' => access_logging_support_configuration, 'redis_store' => redis_store_configuration, - 'external_configuration' => tomcat_external_configuration } + 'tomcat' => tomcat_configuration } end - let(:tomcat_configuration) { { 'external_configuration_enabled' => false } } + let(:access_logging_support_configuration) { instance_double('logging-support-configuration') } let(:lifecycle_support_configuration) { instance_double('lifecycle-support-configuration') } let(:logging_support_configuration) { instance_double('logging-support-configuration') } - let(:access_logging_support_configuration) { instance_double('logging-support-configuration') } + let(:geode_store_configuration) { instance_double('geode_store_configuration') } let(:redis_store_configuration) { instance_double('redis-store-configuration') } + let(:tomcat_configuration) { { 'external_configuration_enabled' => false } } + let(:tomcat_external_configuration) { instance_double('tomcat_external_configuration') } it 'detects WEB-INF', @@ -69,17 +73,19 @@ end it 'creates submodules' do + allow(JavaBuildpack::Container::TomcatAccessLoggingSupport) + .to receive(:new).with(sub_configuration_context(access_logging_support_configuration)) + allow(JavaBuildpack::Container::TomcatGeodeStore) + .to receive(:new).with(sub_configuration_context(geode_store_configuration)) allow(JavaBuildpack::Container::TomcatInstance) .to receive(:new).with(sub_configuration_context(tomcat_configuration)) + allow(JavaBuildpack::Container::TomcatInsightSupport).to receive(:new).with(context) allow(JavaBuildpack::Container::TomcatLifecycleSupport) .to receive(:new).with(sub_configuration_context(lifecycle_support_configuration)) allow(JavaBuildpack::Container::TomcatLoggingSupport) .to receive(:new).with(sub_configuration_context(logging_support_configuration)) - allow(JavaBuildpack::Container::TomcatAccessLoggingSupport) - .to receive(:new).with(sub_configuration_context(access_logging_support_configuration)) allow(JavaBuildpack::Container::TomcatRedisStore) .to receive(:new).with(sub_configuration_context(redis_store_configuration)) - allow(JavaBuildpack::Container::TomcatInsightSupport).to receive(:new).with(context) component.sub_components context end From f5fa652ee81e8122da82c7729d5de0b71b591287 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 19 Jul 2017 09:43:10 -0700 Subject: [PATCH 320/812] Configure Class Count Previously, the class_count memory calculator parameter was not defined in the configuration YAML files where it was legal. This meant that the buildpack automatically discarded any attempt to configure it, as it was not considered a legal value. This change adds the key to the configuration, with an empty value ensure that is configurable with an environment variable and defaults to the calculated value when it is not. [resolves #464] --- config/open_jdk_jre.yml | 1 + config/oracle_jre.yml | 1 + config/zulu_jre.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index c9d7c785be..e8b5a534fc 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -25,4 +25,5 @@ jvmkill_agent: memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + class_count: stack_threads: 300 diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index a94149901a..a451c45090 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -28,4 +28,5 @@ jvmkill_agent: memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + class_count: stack_threads: 300 diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 2d47936bcd..339ff16b1d 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -28,4 +28,5 @@ jvmkill_agent: memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + class_count: stack_threads: 300 From 21bc414d40eab0836fd547afae94e3902d188db5 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 19 Jul 2017 11:32:29 -0700 Subject: [PATCH 321/812] Client Certificate Mapper This change adds a framework that adds a Servlet Filter that maps the X -Forwarded-Client-Cert header to the `javax.servlet.request.X509Certificate` Servlet attribute. This enables applications to make use of mTLS client certificates that have been terminated at the Cloud Foundry router. --- config/client_certificate_mapper.yml | 19 ++++++++ config/components.yml | 1 + java-buildpack.iml | 1 - .../framework/client_certificate_mapper.rb | 46 ++++++++++++++++++ .../stub-client-certificate-mapper.jar | Bin 0 -> 341 bytes .../client_certificate_mapper_spec.rb | 44 +++++++++++++++++ 6 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 config/client_certificate_mapper.yml create mode 100644 lib/java_buildpack/framework/client_certificate_mapper.rb create mode 100644 spec/fixtures/stub-client-certificate-mapper.jar create mode 100644 spec/java_buildpack/framework/client_certificate_mapper_spec.rb diff --git a/config/client_certificate_mapper.yml b/config/client_certificate_mapper.yml new file mode 100644 index 0000000000..33635b822c --- /dev/null +++ b/config/client_certificate_mapper.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Container security provider configuration +--- +version: 1.+ +repository_root: "{default.repository.root}/client-certificate-mapper" diff --git a/config/components.yml b/config/components.yml index 0b42b12d13..a47ce2b59a 100644 --- a/config/components.yml +++ b/config/components.yml @@ -39,6 +39,7 @@ jres: frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" + - "JavaBuildpack::Framework::ClientCertificateMapper" - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::ContainerSecurityProvider" - "JavaBuildpack::Framework::ContrastSecurityAgent" diff --git a/java-buildpack.iml b/java-buildpack.iml index 437cd87af9..4b07f0dde5 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -269,7 +269,6 @@ - diff --git a/lib/java_buildpack/framework/client_certificate_mapper.rb b/lib/java_buildpack/framework/client_certificate_mapper.rb new file mode 100644 index 0000000000..3187985a06 --- /dev/null +++ b/lib/java_buildpack/framework/client_certificate_mapper.rb @@ -0,0 +1,46 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for contributing an mTLS client certificate mapper to the application. + class ClientCertificateMapper < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + end + + end +end diff --git a/spec/fixtures/stub-client-certificate-mapper.jar b/spec/fixtures/stub-client-certificate-mapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..0878c3ccb50e0696f38ae356e9854c75199158f3 GIT binary patch literal 341 zcmWIWW@Zs#;Nak3$ZLM$#DD}i8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1gx0>v$BCyF#%yMkUj+BFaQAGLPY%l literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb new file mode 100644 index 0000000000..c4483379e0 --- /dev/null +++ b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb @@ -0,0 +1,44 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/client_certificate_mapper' + +describe JavaBuildpack::Framework::ClientCertificateMapper do + include_context 'component_helper' + + it 'always detects' do + expect(component.detect).to eq("client-certificate-mapper=#{version}") + end + + it 'adds the jar to the additional libraries during compile', + cache_fixture: 'stub-client-certificate-mapper.jar' do + + component.compile + + expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist + expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") + end + + it 'adds the jar to the additional libraries during release', + cache_fixture: 'stub-client-certificate-mapper.jar' do + + component.release + + expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") + end + +end From dece7b3febd019c009e7acecfeeadf97be9ef508 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 19 Jul 2017 12:14:21 -0700 Subject: [PATCH 322/812] Test Fix This change ensures that the tests will pass now that the "default" detect string is longer than 255 characters. --- spec/bin/detect_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/bin/detect_spec.rb b/spec/bin/detect_spec.rb index 05ca3aaf40..0c522eea58 100644 --- a/spec/bin/detect_spec.rb +++ b/spec/bin/detect_spec.rb @@ -24,7 +24,7 @@ run("bin/detect #{app_dir}") do |status| expect(status).to be_success - expect(stdout.string.rstrip.length).to be < 255 + expect(stdout.string.rstrip.length).to be <= 255 end end From 8b42f77d3f1293325eac3bcb8a452b477886b288 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 19 Jul 2017 12:27:24 -0700 Subject: [PATCH 323/812] Missing Name Mappings Cause Failure Previously, missing name mappings in the versions tasks would show up with UNKNOWN. This was easy to miss in the CI system, leading them to be unset when release time came around. This change ensures that missing name mappings cause a failure forcing it to be dealt with early. --- rakelib/versions_task.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index e33ff2bc4c..b17e81191f 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -179,9 +179,12 @@ def dependency_versions index_configuration(configuration).each do |index_configuration| version, uri = get_from_cache(cache, configuration, index_configuration) + name = NAME_MAPPINGS[id] + raise "Unable to resolve name for '#{id}'" unless name + dependency_versions << { 'id' => id, - 'name' => NAME_MAPPINGS[id] || "UNKNOWN (#{id})", + 'name' => name, 'uri' => uri, 'version' => version } From f848589e7ac386dab74223132aa26f344a21fe2c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 19 Jul 2017 12:27:55 -0700 Subject: [PATCH 324/812] Add Missing Name Mappings This change adds the missing version name mappings. --- rakelib/versions_task.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index b17e81191f..0b25a7d55f 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -50,13 +50,17 @@ def initialize NAME_MAPPINGS = { 'access_logging_support' => 'Tomcat Access Logging Support', + 'agent' => 'Java Memory Assistant Agent', 'app_dynamics_agent' => 'AppDynamics Agent', + 'clean_up' => 'Java Memory Assistant Clean Up', + 'client_certificate_mapper' => 'Client Certificate Mapper', 'container_customizer' => 'Spring Boot Container Customizer', 'container_security_provider' => 'Container Security Provider', 'contrast_security_agent' => 'Contrast Security Agent', 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', 'dynatrace_one_agent' => 'Dynatrace OneAgent', + 'geode_store' => 'Apache Geode Tomcat Session Store', 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', 'groovy' => 'Groovy', 'jre' => 'OpenJDK JRE', From d83ca142161b67d3bc372b1965b1d9eaa525ee3d Mon Sep 17 00:00:00 2001 From: Steve Hiehn Date: Wed, 19 Jul 2017 16:15:42 -0400 Subject: [PATCH 325/812] Pivotal Cloud Cache Documentation This change adds Pivotal Cloud Cache documentation to the buildpack. [resolves #466] --- docs/container-tomcat.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index 0808db831e..f758edf8e0 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -91,6 +91,21 @@ By default, the Tomcat instance is configured to store all Sessions and their da ### Redis To enable Redis-based session replication, simply bind a Redis service containing a name, label, or tag that has `session-replication` as a substring. +### Pivotal Cloud Cache +To enable session state caching on 'Pivotal Cloud Cache', bind to a 'Pivotal Cloud Cache' service instance who's name either ends in `-session-replication` or is tagged with `session-replication`. + +Service instances can be created with a tag: + +```sh +$ cf create-service p-cloudcache my-service-instance -t session-replication +``` + +or existing service instances can be given a tag: + +```sh +$ cf update-service new-service-instance -t session-replication +``` + ## Managing Entropy Entropy from `/dev/random` is used heavily to create session ids, and on startup for initializing `SecureRandom`, which can then cause instances to fail to start in time (see the [Tomcat wiki]). Also, the entropy is shared so it's possible for a single app to starve the DEA of entropy and cause apps in other containers that make use of entropy to be blocked. If this is an issue then configuring `/dev/urandom` as an alternative source of entropy may help. It is unlikely, but possible, that this may cause some security issues which should be taken in to account. From 8bd2ada611ed378cee8b22a42067b0b57a759add Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 20 Jul 2017 10:02:03 -0700 Subject: [PATCH 326/812] Polishing --- config/java_memory_assistant.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/config/java_memory_assistant.yml b/config/java_memory_assistant.yml index 21fd798c19..b1913f79de 100644 --- a/config/java_memory_assistant.yml +++ b/config/java_memory_assistant.yml @@ -17,20 +17,20 @@ enabled: false agent: version: 0.+ repository_root: https://raw.githubusercontent.com/SAP/java-memory-assistant/repository - heap_dump_folder: + heap_dump_folder: check_interval: 5s max_frequency: 1/1m - log_level: + log_level: thresholds: - heap: - code_cache: - metaspace: - perm_gen: - compressed_class: - eden: - survivor: + heap: + code_cache: + metaspace: + perm_gen: + compressed_class: + eden: + survivor: old_gen: ">600MB" clean_up: version: 0.+ repository_root: https://raw.githubusercontent.com/SAP/java-memory-assistant-tools/repository-cu - max_dump_count: 1 \ No newline at end of file + max_dump_count: 1 From 727297d506b3b4de235862716fd149306b5115df Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 20 Jul 2017 09:48:55 -0700 Subject: [PATCH 327/812] Create Release Script This change adds a create-release.sh script to the project to automate the creation of releases. --- ci/create-release.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100755 ci/create-release.sh diff --git a/ci/create-release.sh b/ci/create-release.sh new file mode 100755 index 0000000000..943ddf8931 --- /dev/null +++ b/ci/create-release.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env sh + +set -e -u + +RELEASE=$1 + +echo "---" > config/version.yml +echo "version: v$RELEASE" >> config/version.yml + +bundle exec rake clobber package +mv build/*-buildpack-v$RELEASE.zip $HOME/Desktop + +bundle exec rake clobber package OFFLINE=true PINNED=true +mv build/*-buildpack-offline-v$RELEASE.zip $HOME/Desktop + +bundle exec rake versions:markdown versions:json + +git add . +git commit --message "v$RELEASE Release" +git tag -s v$RELEASE -m "v$RELEASE" +git reset --hard HEAD^1 From a631df86f8aa689f59da51153dd5c83d160a45bd Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 20 Jul 2017 13:58:02 -0700 Subject: [PATCH 328/812] Correct Example Previously, the example described how to change the version of Java to 7, but then demonstrated how to change it to 8. This change fixes the example to match the description. [resolves #468] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f834f828e..5611ab07bd 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ The buildpack supports extension through the use of Git repository forking. The Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec ([Wikipedia] has a good description of this yaml syntax). For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. ```bash -$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ jre: { version: 1.8.0_+ }, memory_calculator: { stack_threads: 200 } }' +$ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ jre: { version: 1.7.0_+ }, memory_calculator: { stack_threads: 200 } }' ``` If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. From a14e12facf49b0d553fb331a9d2655fc2b64b0f3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 26 Jul 2017 14:13:03 -0700 Subject: [PATCH 329/812] Add License Files to Package Previously the LICENSE and NOTICE files were not included in packaged versions of the buildpack. This change adds those files to the package. --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index b87362c3cf..30855160a8 100644 --- a/Rakefile +++ b/Rakefile @@ -38,7 +38,7 @@ require 'rakelib/stage_buildpack_task' require 'rakelib/package_task' require 'rakelib/versions_task' Package::DependencyCacheTask.new -Package::StageBuildpackTask.new(Dir['bin/**/*', 'config/**/*', 'lib/**/*', 'resources/**/*'] +Package::StageBuildpackTask.new(Dir['bin/**/*', 'config/**/*', 'lib/**/*', 'resources/**/*', 'LICENSE', 'NOTICE'] .reject { |f| File.directory? f }) Package::PackageTask.new Package::VersionsTask.new From 6c8d37bd78705c7fa3c72bea2d003429c0746a03 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 31 Jul 2017 11:07:15 -0700 Subject: [PATCH 330/812] Client Certificate Mapper Documentation This change adds the missing documentation for the Client Certificate Mapper. --- README.md | 1 + docs/framework-client_certificate_mapper.md | 34 +++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 docs/framework-client_certificate_mapper.md diff --git a/README.md b/README.md index 5611ab07bd..8dfd1764c2 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) + * [Client Certificate Mapper](docs/framework-client_certificate_mapper.md) ([Configuration](docs/framework-client_certificate_mapper.md#configuration)) * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) * [Container Security Provider](docs/framework-container_security_provider.md) ([Configuration](docs/framework-container_security_provider.md#configuration)) * [Contrast Security Agent](docs/framework-contrast_security_agent.md) ([Configuration](docs/framework-contrast_security_agent.md#configuration)) diff --git a/docs/framework-client_certificate_mapper.md b/docs/framework-client_certificate_mapper.md new file mode 100644 index 0000000000..1927985803 --- /dev/null +++ b/docs/framework-client_certificate_mapper.md @@ -0,0 +1,34 @@ +# Client Certificate Mapper +The Client Certificate Mapper Framework adds a Servlet Filter to applications that will that maps the `X-Forwarded-Client-Cert` to the `javax.servlet.request.X509Certificate` Servlet attribute. + + + + + + + + + + +
Detection CriterionUnconditional
Tagsclient-certificate-mapper=<version>
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/client_certificate_mapper.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Container Customizer repository index ([details][repositories]). +| `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. + +## Servlet Filter +The [Servlet Filter][] added by this framework maps the `X-Forwarded-Client-Cert` to the `javax.servlet.request.X509Certificate` Servlet attribute for each request. The `X-Forwarded-Client-Cert` header is contributed by the Cloud Foundry Router and contains the any TLS certificate presented by a client for mututal TLS authentication. This certificate can then be used by any standard Java security framework to establish authentication and authorization for a request. + +[`config/client_certificate_mapper.yml`]: ../config/client_certificate_mapper.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[repositories]: extending-repositories.md +[Servlet Filter]: https://github.com/cloudfoundry/java-buildpack-client-certificate-mapper +[this listing]: http://download.pivotal.io.s3.amazonaws.com/container-security-provider/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering From 28d5830a6aeaa51f1e0e024e29f790eff03ebe63 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 31 Jul 2017 13:33:20 -0700 Subject: [PATCH 331/812] Better Compile Logging This change improves the compile logging for the Debug and JMX frameworks. This will enable users to see at compile time that they've been enabled and what ports they'll be listening on. --- lib/java_buildpack/framework/debug.rb | 4 +++- lib/java_buildpack/framework/jmx.rb | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index 9d236036dc..014cd2c769 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -29,7 +29,9 @@ def detect end # (see JavaBuildpack::Component::BaseComponent#compile) - def compile; end + def compile + puts "-----> Debugging Enabled on port #{port}#{', suspended on start' if @configuration['suspend']}" + end # (see JavaBuildpack::Component::BaseComponent#release) def release diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index d2fa86d12d..0639c7f72f 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -29,7 +29,9 @@ def detect end # (see JavaBuildpack::Component::BaseComponent#compile) - def compile; end + def compile + puts "-----> JMX Enabled on port #{port}" + end # (see JavaBuildpack::Component::BaseComponent#release) def release From 7af534690c0ed020f0ce9a2cd79d0d6a8a4049ea Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 31 Jul 2017 14:55:36 -0700 Subject: [PATCH 332/812] Polishing --- .idea/.rakeTasks | 2 +- README.md | 112 +++++++++++++------------- lib/java_buildpack/framework/debug.rb | 2 +- lib/java_buildpack/framework/jmx.rb | 2 +- 4 files changed, 59 insertions(+), 59 deletions(-) diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index 28643eaeb3..d167d0de90 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/README.md b/README.md index 8dfd1764c2..47d183781e 100644 --- a/README.md +++ b/README.md @@ -44,15 +44,15 @@ $ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{ arguments: "-server.port=\$P Environment variable can also be specified in the applications `manifest` file. For example, to specify an environment variable in an applications manifest file that disables Auto-reconfiguration. ```bash - env: - JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{ enabled: false }' +env: + JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{ enabled: false }' ``` This final example shows how to change the version of Tomcat that is used by the buildpack with an environment variable specified in the applications manifest file. ```bash - env: - JBP_CONFIG_TOMCAT: '{ tomcat: { version: 8.0.+ } }' +env: + JBP_CONFIG_TOMCAT: '{ tomcat: { version: 8.0.+ } }' ``` See the [Environment Variables][] documentation for more information. @@ -63,64 +63,64 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Design](docs/design.md) * [Security](docs/security.md) * Standard Containers - * [Dist ZIP](docs/container-dist_zip.md) - * [Groovy](docs/container-groovy.md) ([Configuration](docs/container-groovy.md#configuration)) - * [Java Main](docs/container-java_main.md) ([Configuration](docs/container-java_main.md#configuration)) - * [Play Framework](docs/container-play_framework.md) - * [Ratpack](docs/container-ratpack.md) - * [Spring Boot](docs/container-spring_boot.md) - * [Spring Boot CLI](docs/container-spring_boot_cli.md) ([Configuration](docs/container-spring_boot_cli.md#configuration)) - * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) + * [Dist ZIP](docs/container-dist_zip.md) + * [Groovy](docs/container-groovy.md) ([Configuration](docs/container-groovy.md#configuration)) + * [Java Main](docs/container-java_main.md) ([Configuration](docs/container-java_main.md#configuration)) + * [Play Framework](docs/container-play_framework.md) + * [Ratpack](docs/container-ratpack.md) + * [Spring Boot](docs/container-spring_boot.md) + * [Spring Boot CLI](docs/container-spring_boot_cli.md) ([Configuration](docs/container-spring_boot_cli.md#configuration)) + * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) * Standard Frameworks - * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) - * [Client Certificate Mapper](docs/framework-client_certificate_mapper.md) ([Configuration](docs/framework-client_certificate_mapper.md#configuration)) - * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) - * [Container Security Provider](docs/framework-container_security_provider.md) ([Configuration](docs/framework-container_security_provider.md#configuration)) - * [Contrast Security Agent](docs/framework-contrast_security_agent.md) ([Configuration](docs/framework-contrast_security_agent.md#configuration)) - * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) - * [Dyadic EKM Security Provider](docs/framework-dyadic_ekm_security_provider.md) ([Configuration](docs/framework-dyadic_ekm_security_provider.md#configuration)) - * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) - * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) - * [Google Stackdriver Debugger](docs/framework-google_stackdriver_debugger.md) ([Configuration](docs/framework-google_stackdriver_debugger.md#configuration)) - * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) - * [Java Memory Assistant](docs/framework-java_memory_assistant.md) ([Configuration](docs/framework-java_memory_assistant.md#configuration)) - * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) - * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) - * [JMX](docs/framework-jmx.md) ([Configuration](docs/framework-jmx.md#configuration)) - * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) - * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) (also supports MySQL) - * [Metric Writer](docs/framework-metric_writer.md) ([Configuration](docs/framework-metric_writer.md#configuration)) - * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) - * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) - * [Play Framework JPA Plugin](docs/framework-play_framework_jpa_plugin.md) ([Configuration](docs/framework-play_framework_jpa_plugin.md#configuration)) - * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) - * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) - * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) - * [Spring Insight](docs/framework-spring_insight.md) - * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) + * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) + * [Client Certificate Mapper](docs/framework-client_certificate_mapper.md) ([Configuration](docs/framework-client_certificate_mapper.md#configuration)) + * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) + * [Container Security Provider](docs/framework-container_security_provider.md) ([Configuration](docs/framework-container_security_provider.md#configuration)) + * [Contrast Security Agent](docs/framework-contrast_security_agent.md) ([Configuration](docs/framework-contrast_security_agent.md#configuration)) + * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) + * [Dyadic EKM Security Provider](docs/framework-dyadic_ekm_security_provider.md) ([Configuration](docs/framework-dyadic_ekm_security_provider.md#configuration)) + * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) + * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) + * [Google Stackdriver Debugger](docs/framework-google_stackdriver_debugger.md) ([Configuration](docs/framework-google_stackdriver_debugger.md#configuration)) + * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) + * [Java Memory Assistant](docs/framework-java_memory_assistant.md) ([Configuration](docs/framework-java_memory_assistant.md#configuration)) + * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) + * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) + * [JMX](docs/framework-jmx.md) ([Configuration](docs/framework-jmx.md#configuration)) + * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) + * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) (also supports MySQL) + * [Metric Writer](docs/framework-metric_writer.md) ([Configuration](docs/framework-metric_writer.md#configuration)) + * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) + * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) + * [Play Framework JPA Plugin](docs/framework-play_framework_jpa_plugin.md) ([Configuration](docs/framework-play_framework_jpa_plugin.md#configuration)) + * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) + * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) + * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) + * [Spring Insight](docs/framework-spring_insight.md) + * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) * Standard JREs - * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) - * [IBM® SDK, Java™ Technology Edition](docs/jre-ibm_jre.md) ([Configuration](docs/jre-ibm_jre.md#configuration)) - * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) - * [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration)) + * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) + * [IBM® SDK, Java™ Technology Edition](docs/jre-ibm_jre.md) ([Configuration](docs/jre-ibm_jre.md#configuration)) + * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) + * [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration)) * [Extending](docs/extending.md) - * [Application](docs/extending-application.md) - * [Droplet](docs/extending-droplet.md) - * [BaseComponent](docs/extending-base_component.md) - * [VersionedDependencyComponent](docs/extending-versioned_dependency_component.md) - * [ModularComponent](docs/extending-modular_component.md) - * [Caches](docs/extending-caches.md) ([Configuration](docs/extending-caches.md#configuration)) - * [Logging](docs/extending-logging.md) ([Configuration](docs/extending-logging.md#configuration)) - * [Repositories](docs/extending-repositories.md) ([Configuration](docs/extending-repositories.md#configuration)) - * [Utilities](docs/extending-utilities.md) + * [Application](docs/extending-application.md) + * [Droplet](docs/extending-droplet.md) + * [BaseComponent](docs/extending-base_component.md) + * [VersionedDependencyComponent](docs/extending-versioned_dependency_component.md) + * [ModularComponent](docs/extending-modular_component.md) + * [Caches](docs/extending-caches.md) ([Configuration](docs/extending-caches.md#configuration)) + * [Logging](docs/extending-logging.md) ([Configuration](docs/extending-logging.md#configuration)) + * [Repositories](docs/extending-repositories.md) ([Configuration](docs/extending-repositories.md#configuration)) + * [Utilities](docs/extending-utilities.md) * [Debugging the Buildpack](docs/debugging-the-buildpack.md) * [Buildpack Modes](docs/buildpack-modes.md) * Related Projects - * [Java Buildpack Dependency Builder](https://github.com/cloudfoundry/java-buildpack-dependency-builder) - * [Java Buildpack Memory Calculator](https://github.com/cloudfoundry/java-buildpack-memory-calculator) - * [Java Test Applications](https://github.com/cloudfoundry/java-test-applications) - * [Java Buildpack System Tests](https://github.com/cloudfoundry/java-buildpack-system-test) - * [jvmkill](https://github.com/cloudfoundry/jvmkill) + * [Java Buildpack Dependency Builder](https://github.com/cloudfoundry/java-buildpack-dependency-builder) + * [Java Buildpack Memory Calculator](https://github.com/cloudfoundry/java-buildpack-memory-calculator) + * [Java Test Applications](https://github.com/cloudfoundry/java-test-applications) + * [Java Buildpack System Tests](https://github.com/cloudfoundry/java-buildpack-system-test) + * [jvmkill](https://github.com/cloudfoundry/jvmkill) ## Building Packages The buildpack can be packaged up so that it can be uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used. diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index 014cd2c769..21b17e79fa 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -25,7 +25,7 @@ class Debug < JavaBuildpack::Component::BaseComponent # (see JavaBuildpack::Component::BaseComponent#detect) def detect - enabled? ? "#{Debug.to_s.dash_case}=#{port}" : nil + enabled? ? "#{self.class.to_s.dash_case}=#{port}" : nil end # (see JavaBuildpack::Component::BaseComponent#compile) diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 0639c7f72f..65b7ee9f77 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -25,7 +25,7 @@ class Jmx < JavaBuildpack::Component::BaseComponent # (see JavaBuildpack::Component::BaseComponent#detect) def detect - enabled? ? "#{Jmx.to_s.dash_case}=#{port}" : nil + enabled? ? "#{self.class.to_s.dash_case}=#{port}" : nil end # (see JavaBuildpack::Component::BaseComponent#compile) From 64165665fb3c55719f2fcc84615b7222e6143a91 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 31 Jul 2017 15:28:52 -0700 Subject: [PATCH 333/812] AspectJ Weaver Agent This change adds the AspectJ Weaver Agent which will detect the existing of an aop.xml and the aspectjweaver JAR and configure runtime weaving if they both exist. [resolves #473] --- README.md | 1 + config/aspectj_weaver_agent.yml | 18 +++++ config/components.yml | 1 + docs/framework-aspectj_weaver_agent.md | 26 +++++++ .../framework/aspectj_weaver_agent.rb | 75 +++++++++++++++++++ .../BOOT-INF/classes/META-INF/aop.xml | 0 .../BOOT-INF/classes/org/aspectj/aop.xml | 0 .../BOOT-INF/lib/aspectjweaver-1.8.10.jar | 0 .../BOOT-INF/classes/META-INF/aop.xml | 0 .../BOOT-INF/lib/aspectjweaver-1.8.10.jar | 0 .../BOOT-INF/lib/aspectjweaver-1.8.10.jar | 0 .../BOOT-INF/lib/aspectjweaver-1.8.10.jar | 0 .../META-INF/aop.xml | 0 .../framework/aspectj_weaver_agent_spec.rb | 68 +++++++++++++++++ 14 files changed, 189 insertions(+) create mode 100644 config/aspectj_weaver_agent.yml create mode 100644 docs/framework-aspectj_weaver_agent.md create mode 100644 lib/java_buildpack/framework/aspectj_weaver_agent.rb create mode 100644 spec/fixtures/framework_aspectj_weaver_aop_xml_only/BOOT-INF/classes/META-INF/aop.xml create mode 100644 spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/classes/org/aspectj/aop.xml create mode 100644 spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/lib/aspectjweaver-1.8.10.jar create mode 100644 spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/classes/META-INF/aop.xml create mode 100644 spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar create mode 100644 spec/fixtures/framework_aspectj_weaver_jar_only/BOOT-INF/lib/aspectjweaver-1.8.10.jar create mode 100644 spec/fixtures/framework_aspectj_weaver_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar create mode 100644 spec/fixtures/framework_aspectj_weaver_meta_inf/META-INF/aop.xml create mode 100644 spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb diff --git a/README.md b/README.md index 47d183781e..409a8cb32b 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration)) * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) + * [AspectJ Weaver Agent](docs/framework-aspectj_weaver_agent.md) ([Configuration](docs/framework-aspectj_weaver_agent.md#configuration)) * [Client Certificate Mapper](docs/framework-client_certificate_mapper.md) ([Configuration](docs/framework-client_certificate_mapper.md#configuration)) * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) * [Container Security Provider](docs/framework-container_security_provider.md) ([Configuration](docs/framework-container_security_provider.md#configuration)) diff --git a/config/aspectj_weaver_agent.yml b/config/aspectj_weaver_agent.yml new file mode 100644 index 0000000000..19c3c217df --- /dev/null +++ b/config/aspectj_weaver_agent.yml @@ -0,0 +1,18 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# AspectJ Weaver Agent configuration +--- +enabled: true diff --git a/config/components.yml b/config/components.yml index 7c6bfc1daa..4fdf32063f 100644 --- a/config/components.yml +++ b/config/components.yml @@ -38,6 +38,7 @@ jres: # command after any Java Opts added by previous frameworks. frameworks: - "JavaBuildpack::Framework::AppDynamicsAgent" + - "JavaBuildpack::Framework::AspectjWeaverAgent" - "JavaBuildpack::Framework::ClientCertificateMapper" - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::ContainerSecurityProvider" diff --git a/docs/framework-aspectj_weaver_agent.md b/docs/framework-aspectj_weaver_agent.md new file mode 100644 index 0000000000..874869750f --- /dev/null +++ b/docs/framework-aspectj_weaver_agent.md @@ -0,0 +1,26 @@ +# AspectJ Weaver Agent Framework +The AspectJ Weaver Agent Framework configures the AspectJ Runtime Weaving Agent at runtime. + + + + + + + + + + +
Detection Criterionaspectjweaver-*.jar existing and BOOT-INF/classes/META-INF/aop.xml, BOOT-INF/classes/org/aspectj/aop.xml, or META-INF/aop.xml existing.
Tagsaspectj-weaver-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by creating or modifying the [`config/aspectj_weaver_agent.yml`][] file in the buildpack fork. + +| Name | Description +| ---- | ----------- +| `enabled` | Whether to enable the AspectJ Runtime Weaving agent. + +[`config/aspectj_weaver_agent.yml`]: ../config/aspect_weaver_agent.yml +[Configuration and Extension]: ../README.md#configuration-and-extension diff --git a/lib/java_buildpack/framework/aspectj_weaver_agent.rb b/lib/java_buildpack/framework/aspectj_weaver_agent.rb new file mode 100644 index 0000000000..11788775be --- /dev/null +++ b/lib/java_buildpack/framework/aspectj_weaver_agent.rb @@ -0,0 +1,75 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/base_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/dash_case' +require 'java_buildpack/util/jar_finder' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for contributing AspectJ Runtime Weaving configuration an application. + class AspectjWeaverAgent < JavaBuildpack::Component::BaseComponent + + # Creates an instance. In addition to the functionality inherited from +BaseComponent+, +@version+ and +@uri+ + # instance variables are exposed. + # + # @param [Hash] context a collection of utilities used by components + def initialize(context) + super(context) + + @jar_finder = JavaBuildpack::Util::JarFinder.new(/.*aspectjweaver-([\d].*)\.jar/) + end + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + supports? ? "#{self.class.to_s.dash_case}=#{@jar_finder.version(@application)}" : nil + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + puts "-----> AspectJ #{version} Runtime Weaving Enabled" + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts.add_javaagent @jar_finder.is?(@application) + end + + private + + def aop_xml_exist? + (@application.root + 'BOOT-INF/classes/META-INF/aop.xml').exist? || + (@application.root + 'BOOT-INF/classes/org/aspectj/aop.xml').exist? || + (@application.root + 'META-INF/aop.xml').exist? + end + + def enabled? + @configuration['enabled'] + end + + def supports? + enabled? && @jar_finder.is?(@application) && aop_xml_exist? + end + + def version + @jar_finder.version(@application) + end + + end + + end +end diff --git a/spec/fixtures/framework_aspectj_weaver_aop_xml_only/BOOT-INF/classes/META-INF/aop.xml b/spec/fixtures/framework_aspectj_weaver_aop_xml_only/BOOT-INF/classes/META-INF/aop.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/classes/org/aspectj/aop.xml b/spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/classes/org/aspectj/aop.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/lib/aspectjweaver-1.8.10.jar b/spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/lib/aspectjweaver-1.8.10.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/classes/META-INF/aop.xml b/spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/classes/META-INF/aop.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar b/spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_aspectj_weaver_jar_only/BOOT-INF/lib/aspectjweaver-1.8.10.jar b/spec/fixtures/framework_aspectj_weaver_jar_only/BOOT-INF/lib/aspectjweaver-1.8.10.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_aspectj_weaver_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar b/spec/fixtures/framework_aspectj_weaver_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_aspectj_weaver_meta_inf/META-INF/aop.xml b/spec/fixtures/framework_aspectj_weaver_meta_inf/META-INF/aop.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb b/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb new file mode 100644 index 0000000000..300d4c2343 --- /dev/null +++ b/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb @@ -0,0 +1,68 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/aspectj_weaver_agent' + +describe JavaBuildpack::Framework::AspectjWeaverAgent do + include_context 'component_helper' + + it 'does not detect if not enabled' do + expect(component.detect).to be_nil + end + + context do + let(:configuration) { { 'enabled' => true } } + + it 'does not detect if aop.xml only', + app_fixture: 'framework_aspectj_weaver_aop_xml_only' do + + expect(component.detect).to be_nil + end + + it 'detects when aop.xml in classes', + app_fixture: 'framework_aspectj_weaver_classes' do + + expect(component.detect).to eq('aspectj-weaver-agent=1.8.10') + end + + it 'detects when aop.xml in classes/META-INF', + app_fixture: 'framework_aspectj_weaver_classes_meta_inf' do + + expect(component.detect).to eq('aspectj-weaver-agent=1.8.10') + end + + it 'does not detect if JAR only', + app_fixture: 'framework_aspectj_weaver_jar_only' do + + expect(component.detect).to be_nil + end + + it 'detects when aop.xml in META-INF', + app_fixture: 'framework_aspectj_weaver_meta_inf' do + + expect(component.detect).to eq('aspectj-weaver-agent=1.8.10') + end + + it 'adds java agent', + app_fixture: 'framework_aspectj_weaver_classes' do + + component.release + expect(java_opts).to include('-javaagent:$PWD/BOOT-INF/lib/aspectjweaver-1.8.10.jar') + end + end + +end From d259942b6c2e0d57767960bb5c0df8ff9ceff386 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 1 Aug 2017 09:40:03 -0700 Subject: [PATCH 334/812] Additional aop.xml Location Previously, the search for aop.xml only search for Spring Boot typical locations, as well as `META-INF/aop.xml`. It missed the class package location for non-Boot application. This change adds a search in `org/aspect/aop.xml` in non-Boot application. [#473] --- docs/framework-aspectj_weaver_agent.md | 2 +- .../framework/aspectj_weaver_agent.rb | 3 ++- .../BOOT-INF/classes/org/aspectj/aop.xml | 0 .../BOOT-INF/lib/aspectjweaver-1.8.10.jar | 0 .../BOOT-INF/classes/META-INF/aop.xml | 0 .../BOOT-INF/lib/aspectjweaver-1.8.10.jar | 0 .../org/aspectj/aop.xml | 0 .../framework/aspectj_weaver_agent_spec.rb | 16 +++++++++++----- 8 files changed, 14 insertions(+), 7 deletions(-) rename spec/fixtures/{framework_aspectj_weaver_classes => framework_aspectj_weaver_boot_inf_classes}/BOOT-INF/classes/org/aspectj/aop.xml (100%) rename spec/fixtures/{framework_aspectj_weaver_classes_meta_inf => framework_aspectj_weaver_boot_inf_classes}/BOOT-INF/lib/aspectjweaver-1.8.10.jar (100%) rename spec/fixtures/{framework_aspectj_weaver_classes_meta_inf => framework_aspectj_weaver_boot_inf_classes_meta_inf}/BOOT-INF/classes/META-INF/aop.xml (100%) create mode 100644 spec/fixtures/framework_aspectj_weaver_boot_inf_classes_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar create mode 100644 spec/fixtures/framework_aspectj_weaver_classes/org/aspectj/aop.xml diff --git a/docs/framework-aspectj_weaver_agent.md b/docs/framework-aspectj_weaver_agent.md index 874869750f..926315defe 100644 --- a/docs/framework-aspectj_weaver_agent.md +++ b/docs/framework-aspectj_weaver_agent.md @@ -4,7 +4,7 @@ The AspectJ Weaver Agent Framework configures the AspectJ Runtime Weaving Agent - + diff --git a/lib/java_buildpack/framework/aspectj_weaver_agent.rb b/lib/java_buildpack/framework/aspectj_weaver_agent.rb index 11788775be..466a4a5b16 100644 --- a/lib/java_buildpack/framework/aspectj_weaver_agent.rb +++ b/lib/java_buildpack/framework/aspectj_weaver_agent.rb @@ -54,7 +54,8 @@ def release def aop_xml_exist? (@application.root + 'BOOT-INF/classes/META-INF/aop.xml').exist? || (@application.root + 'BOOT-INF/classes/org/aspectj/aop.xml').exist? || - (@application.root + 'META-INF/aop.xml').exist? + (@application.root + 'META-INF/aop.xml').exist? || + (@application.root + 'org/aspectj/aop.xml').exist? end def enabled? diff --git a/spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/classes/org/aspectj/aop.xml b/spec/fixtures/framework_aspectj_weaver_boot_inf_classes/BOOT-INF/classes/org/aspectj/aop.xml similarity index 100% rename from spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/classes/org/aspectj/aop.xml rename to spec/fixtures/framework_aspectj_weaver_boot_inf_classes/BOOT-INF/classes/org/aspectj/aop.xml diff --git a/spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar b/spec/fixtures/framework_aspectj_weaver_boot_inf_classes/BOOT-INF/lib/aspectjweaver-1.8.10.jar similarity index 100% rename from spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar rename to spec/fixtures/framework_aspectj_weaver_boot_inf_classes/BOOT-INF/lib/aspectjweaver-1.8.10.jar diff --git a/spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/classes/META-INF/aop.xml b/spec/fixtures/framework_aspectj_weaver_boot_inf_classes_meta_inf/BOOT-INF/classes/META-INF/aop.xml similarity index 100% rename from spec/fixtures/framework_aspectj_weaver_classes_meta_inf/BOOT-INF/classes/META-INF/aop.xml rename to spec/fixtures/framework_aspectj_weaver_boot_inf_classes_meta_inf/BOOT-INF/classes/META-INF/aop.xml diff --git a/spec/fixtures/framework_aspectj_weaver_boot_inf_classes_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar b/spec/fixtures/framework_aspectj_weaver_boot_inf_classes_meta_inf/BOOT-INF/lib/aspectjweaver-1.8.10.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_aspectj_weaver_classes/org/aspectj/aop.xml b/spec/fixtures/framework_aspectj_weaver_classes/org/aspectj/aop.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb b/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb index 300d4c2343..112013ae3b 100644 --- a/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb +++ b/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb @@ -33,14 +33,14 @@ expect(component.detect).to be_nil end - it 'detects when aop.xml in classes', - app_fixture: 'framework_aspectj_weaver_classes' do + it 'detects when aop.xml in BOOT-INF classes', + app_fixture: 'framework_aspectj_weaver_boot_inf_classes' do expect(component.detect).to eq('aspectj-weaver-agent=1.8.10') end - it 'detects when aop.xml in classes/META-INF', - app_fixture: 'framework_aspectj_weaver_classes_meta_inf' do + it 'detects when aop.xml in BOOT-INF/classes/META-INF', + app_fixture: 'framework_aspectj_weaver_boot_inf_classes_meta_inf' do expect(component.detect).to eq('aspectj-weaver-agent=1.8.10') end @@ -57,9 +57,15 @@ expect(component.detect).to eq('aspectj-weaver-agent=1.8.10') end - it 'adds java agent', + it 'detects when aop.xml in classes', app_fixture: 'framework_aspectj_weaver_classes' do + expect(component.detect).to eq('aspectj-weaver-agent=1.8.10') + end + + it 'adds java agent', + app_fixture: 'framework_aspectj_weaver_boot_inf_classes' do + component.release expect(java_opts).to include('-javaagent:$PWD/BOOT-INF/lib/aspectjweaver-1.8.10.jar') end From 110e00afbc2431560a4ff3307278f23fd43fc756 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 1 Aug 2017 09:55:37 -0700 Subject: [PATCH 335/812] Additional aspectjweaver JAR Location Previously, the search for aspectweaver-*.jar only searched for Spring Boot typical locations`. It missed JARs in non-Boot applications. This change loosens the search for the JAR so that non-Boot application can be used. [#473] --- lib/java_buildpack/util/jar_finder.rb | 2 +- .../org/aspectj/aspectjweaver/1.8.10}/aspectjweaver-1.8.10.jar | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename spec/fixtures/framework_aspectj_weaver_classes/{BOOT-INF/lib => repository/org/aspectj/aspectjweaver/1.8.10}/aspectjweaver-1.8.10.jar (100%) diff --git a/lib/java_buildpack/util/jar_finder.rb b/lib/java_buildpack/util/jar_finder.rb index 47ba294471..c4c415e3db 100644 --- a/lib/java_buildpack/util/jar_finder.rb +++ b/lib/java_buildpack/util/jar_finder.rb @@ -48,7 +48,7 @@ def version(application) private def jar(application) - (application.root + '**/lib/*.jar').glob.find { |jar| jar.to_s =~ @pattern } + (application.root + '**/*.jar').glob.find { |jar| jar.to_s =~ @pattern } end end diff --git a/spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/lib/aspectjweaver-1.8.10.jar b/spec/fixtures/framework_aspectj_weaver_classes/repository/org/aspectj/aspectjweaver/1.8.10/aspectjweaver-1.8.10.jar similarity index 100% rename from spec/fixtures/framework_aspectj_weaver_classes/BOOT-INF/lib/aspectjweaver-1.8.10.jar rename to spec/fixtures/framework_aspectj_weaver_classes/repository/org/aspectj/aspectjweaver/1.8.10/aspectjweaver-1.8.10.jar From e0d2941844712cbf077e2c6fbfe231713f630821 Mon Sep 17 00:00:00 2001 From: Dhruv Mevada Date: Fri, 21 Jul 2017 14:27:28 -0700 Subject: [PATCH 336/812] Update Introscope Agent Framework Before this commit, the Introscope agent framework had support for the new agent manager uril, but it was missing a few cases. The framework was also disabled by default, so changes had to be made to enable it (e.g. the config/introscope_agent.yml had an empty repository_root). The biggest change was for the agentManager.url.1 property. Since it is now just a url, separate properties for host, port, and ssl do not need to be maintained. All information is encapsulated in the url. The user provides the url, and to allow backwards-compatability, the previous EM connection properties will also be populated with the various components from the agentManager url. After this commit, the buildpack simplifies the user-input so that the user only needs to provide the url, and not the host-name and port. This way, the detection criteria has also been changed so that the url must be provided, and not the host-name. The previous versions of the buildpack were missing support for different socket factories, and with this commit, all socket factories and connection methods (tcp, ssl, http, https) are now supported. Finally, the introscope agent has been enabled out of the box, and the repository root now contains a link to the index.yml file. The documentation has also been updated to reflect these changes. [#470] --- config/components.yml | 2 +- config/introscope_agent.yml | 4 +- docs/framework-introscope_agent.md | 9 +- .../framework/introscope_agent.rb | 63 ++++++----- .../framework/introscope_agent_spec.rb | 106 +++++++++++++----- 5 files changed, 118 insertions(+), 66 deletions(-) diff --git a/config/components.yml b/config/components.yml index 4fdf32063f..801509f144 100644 --- a/config/components.yml +++ b/config/components.yml @@ -48,7 +48,7 @@ frameworks: - "JavaBuildpack::Framework::DynatraceAppmonAgent" - "JavaBuildpack::Framework::DynatraceOneAgent" - "JavaBuildpack::Framework::GoogleStackdriverDebugger" -# - "JavaBuildpack::Framework::IntroscopeAgent" + - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::JavaMemoryAssistant" - "JavaBuildpack::Framework::Jmx" - "JavaBuildpack::Framework::JrebelAgent" diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index b2f5daf1b0..ed68529568 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -15,6 +15,6 @@ # Configuration for the CA Wily framework --- -repository_root: "" -version: 9.7.+ +repository_root: "https://ca.bintray.com/apm-agents" +version: 10.+ default_agent_name: ! '$(ruby -e "require ''json'' ; puts JSON.parse(ENV[''VCAP_APPLICATION''])[''application_name'']")' diff --git a/docs/framework-introscope_agent.md b/docs/framework-introscope_agent.md index ee94e6848c..fc4caf926d 100644 --- a/docs/framework-introscope_agent.md +++ b/docs/framework-introscope_agent.md @@ -1,5 +1,5 @@ -# Introscope Agent Framework -The Introscope Agent Framework causes an application to be automatically configured to work with a bound [Introscope service][]. **Note:** This framework is disabled by default. +# CA Introscope APM Framework +The CA Introscope APM Framework causes an application to be automatically configured to work with a bound [Introscope service][].
Detection Criterionaspectjweaver-*.jar existing and BOOT-INF/classes/META-INF/aop.xml, BOOT-INF/classes/org/aspectj/aop.xml, or META-INF/aop.xml existing.aspectjweaver-*.jar existing and BOOT-INF/classes/META-INF/aop.xml, BOOT-INF/classes/org/aspectj/aop.xml, META-INF/aop.xml, or org/aspectj/aop.xml existing.
Tags
@@ -24,9 +24,8 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- | `agent-name` | (Optional) The name that should be given to this instance of the Introscope agent -| `host-name` | The host name of the Introscope Enterprise Manager server -| `ssl` | (Optional) Whether or not to use an SSL connection to the Introscope Enterprise Manager server -| `port` | (Optional) The port of the Introscope Enterprise Manager server +| `url` | The url of the Introscope Enterprise Manager server + To provide more complex values such as the `agent-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `agent-name` could be set with a value of `agent-$(expr "$VCAP_APPLICATION" : '.*application_name[": ]*\([[:word:]]*\).*')` to calculate a value from the Cloud Foundry application name. diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index 00537200cb..c8af44dcbf 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -41,18 +41,15 @@ def release .add_system_property('introscope.agent.hostName', agent_host_name) .add_system_property('com.wily.introscope.agent.agentName', agent_name(credentials)) .add_system_property('introscope.agent.defaultProcessName', default_process_name) - .add_system_property('introscope.agent.enterprisemanager.transport.tcp.host.DEFAULT', host_name(credentials)) - .add_system_property('agentManager.url.1', agent_manager(credentials)) - add_port(credentials, java_opts) - add_socket_factory(credentials, java_opts) + add_url(credentials, java_opts) end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, 'host-name' + @application.services.one_service? FILTER, 'url' end private @@ -61,17 +58,6 @@ def supports? private_constant :FILTER - def add_port(credentials, java_opts) - port = port(credentials) - java_opts.add_system_property('introscope.agent.enterprisemanager.transport.tcp.port.DEFAULT', port) if port - end - - def add_socket_factory(credentials, java_opts) - return unless ssl?(credentials) - java_opts.add_system_property('introscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT', - 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') - end - def agent_host_name @application.details['application_uris'][0] end @@ -80,12 +66,27 @@ def agent_jar @droplet.sandbox + 'Agent.jar' end - def agent_manager(credentials) - agent_manager = ssl?(credentials) ? 'https://' : 'http://' - agent_manager += host_name(credentials) + def add_url(credentials, java_opts) + agent_manager = url(credentials) - port = port(credentials) - port ? "#{agent_manager}:#{port}" : agent_manager + host, port, socket_factory = parse_url(agent_manager) + java_opts.add_system_property('agentManager.url.1', agent_manager) + java_opts.add_system_property('introscope.agent.enterprisemanager.transport.tcp.host.DEFAULT', host) + java_opts.add_system_property('introscope.agent.enterprisemanager.transport.tcp.port.DEFAULT', port) + java_opts.add_system_property('introscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT', + socket_factory) + end + + # Parse the agent manager url, split first by '://', and then with ':' + # components is of the format [host, port, socket_factory] + def parse_url(url) + components = url.split('://') + components.unshift('') if components.length == 1 + components[1] = components[1].split(':') + components.flatten! + components.push(protocol_mapping(components[0])) + components.shift + components end def agent_name(credentials) @@ -100,18 +101,22 @@ def default_process_name @application.details['application_name'] end - def host_name(credentials) - credentials['host-name'] - end + def protocol_mapping(protocol) + socket_factory_base = 'com.wily.isengard.postofficehub.link.net.' - def port(credentials) - credentials['port'] - end + protocol_socket_factory = { + '' => socket_factory_base + 'DefaultSocketFactory', + 'ssl' => socket_factory_base + 'SSLSocketFactory', + 'http' => socket_factory_base + 'HttpTunnelingSocketFactory', + 'https' => socket_factory_base + 'HttpsTunnelingSocketFactory' + } - def ssl?(credentials) - credentials['ssl'].to_b + protocol_socket_factory[protocol] || protocol end + def url(credentials) + credentials['url'] + end end end end diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index 0dfc9f8761..90b5147668 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -38,7 +38,7 @@ let(:credentials) { {} } before do - allow(services).to receive(:one_service?).with(/introscope/, 'host-name').and_return(true) + allow(services).to receive(:one_service?).with(/introscope/, 'url').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => credentials) end @@ -46,8 +46,7 @@ expect(component.detect).to eq("introscope-agent=#{version}") end - it 'expands Introscope agent zip', - cache_fixture: 'stub-introscope-agent.tar' do + it 'expands Introscope agent zip', cache_fixture: 'stub-introscope-agent.tar' do component.compile @@ -55,10 +54,20 @@ end context do + let(:credentials) { { 'agent-name' => 'another-test-agent-name', 'url' => 'default-host:5001' } } - let(:credentials) { { 'host-name' => 'test-host-name' } } + it 'adds agent-name from credentials to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=another-test-agent-name') + end + end + + context do - it 'updates JAVA_OPTS' do + let(:credentials) { { 'url' => 'test-host-name:5001' } } + + it 'parses the url and sets host port and default socket factory' do component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') @@ -66,46 +75,85 @@ '/config/IntroscopeAgent.profile') expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + + expect(java_opts).to include('-DagentManager.url.1=test-host-name:5001') expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') - expect(java_opts).to include('-DagentManager.url.1=http://test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=5001') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.DefaultSocketFactory') + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end + end + + context do + let(:credentials) { { 'url' => 'ssl://test-host-name:5443' } } - context do - let(:credentials) { super().merge 'agent-name' => 'another-test-agent-name' } + it 'parses the url and sets host, port, and ssl socket factory' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') - it 'adds agent-name from credentials to JAVA_OPTS if specified' do - component.release + expect(java_opts).to include('-DagentManager.url.1=ssl://test-host-name:5443') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=5443') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') - expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=another-test-agent-name') - end + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end + end - context do - let(:credentials) { super().merge 'port' => 'test-port' } + context do + let(:credentials) { { 'url' => 'http://test-host-name:8081' } } - it 'adds port from credentials to JAVA_OPTS if specified' do - component.release + it 'parses the url and sets host, port, and http socket factory' do + component.release - expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=test-port') - expect(java_opts).to include('-DagentManager.url.1=http://test-host-name:test-port') - end + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + + expect(java_opts).to include('-DagentManager.url.1=http://test-host-name:8081') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=8081') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.HttpTunnelingSocketFactory') + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end + end - context do - let(:credentials) { super().merge 'ssl' => 'true' } + context do + let(:credentials) { { 'url' => 'https://test-host-name:8444' } } - it 'adds ssl socket factory from credentials to JAVA_OPTS if specified' do - component.release + it 'parses the url and sets host, port, and https socket factory' do + component.release - expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ - 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') - expect(java_opts).to include('-DagentManager.url.1=https://test-host-name') - end + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + + expect(java_opts).to include('-DagentManager.url.1=https://test-host-name:8444') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=8444') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end end - end - end From 2e642ba238fceff153ec5b7f52eb66764217cff2 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 2 Aug 2017 11:26:16 -0700 Subject: [PATCH 337/812] Polishing [resolves #470] --- lib/java_buildpack/framework/introscope_agent.rb | 6 +++--- rakelib/versions_task.rb | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index c8af44dcbf..19df64fc7a 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -105,9 +105,9 @@ def protocol_mapping(protocol) socket_factory_base = 'com.wily.isengard.postofficehub.link.net.' protocol_socket_factory = { - '' => socket_factory_base + 'DefaultSocketFactory', - 'ssl' => socket_factory_base + 'SSLSocketFactory', - 'http' => socket_factory_base + 'HttpTunnelingSocketFactory', + '' => socket_factory_base + 'DefaultSocketFactory', + 'ssl' => socket_factory_base + 'SSLSocketFactory', + 'http' => socket_factory_base + 'HttpTunnelingSocketFactory', 'https' => socket_factory_base + 'HttpsTunnelingSocketFactory' } diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 6d78b4405c..f8a7ac523a 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -63,6 +63,7 @@ def initialize 'geode_store' => 'Apache Geode Tomcat Session Store', 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', 'groovy' => 'Groovy', + 'introscope_agent' => 'CA Introscope APM Framework', 'jre' => 'OpenJDK JRE', 'jrebel_agent' => 'JRebel Agent', 'jvmkill_agent' => 'jvmkill Agent', From d9c9958a076c6bfd214fa1ac9ef648c602ecf91f Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 4 Aug 2017 10:18:49 -0700 Subject: [PATCH 338/812] Polishing --- config/introscope_agent.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index ed68529568..79a217cfdf 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -15,6 +15,6 @@ # Configuration for the CA Wily framework --- -repository_root: "https://ca.bintray.com/apm-agents" +repository_root: https://ca.bintray.com/apm-agents version: 10.+ -default_agent_name: ! '$(ruby -e "require ''json'' ; puts JSON.parse(ENV[''VCAP_APPLICATION''])[''application_name'']")' +default_agent_name: $(ruby -e "require 'json' ; puts JSON.parse(ENV['VCAP_APPLICATION'])['application_name']") From 02ab5279fb89b4246780271e1d9daa921e2d67fa Mon Sep 17 00:00:00 2001 From: Chen Harel Date: Tue, 25 Jul 2017 11:26:40 +0300 Subject: [PATCH 339/812] Takipi Agent Framework This change adds the Takipi agent framework to the buildpack. This framework supports both the local and remote collector approaches for using the Takipi agent. [#472] --- README.md | 1 + config/components.yml | 1 + config/takipi_agent.yml | 21 ++++ docs/framework-takipi_agent.md | 49 ++++++++ lib/java_buildpack/framework/takipi_agent.rb | 104 +++++++++++++++++ spec/fixtures/stub-takipi-agent.tar.gz | Bin 0 -> 1126 bytes .../framework/takipi_agent_spec.rb | 105 ++++++++++++++++++ 7 files changed, 281 insertions(+) create mode 100644 config/takipi_agent.yml create mode 100644 docs/framework-takipi_agent.md create mode 100644 lib/java_buildpack/framework/takipi_agent.rb create mode 100644 spec/fixtures/stub-takipi-agent.tar.gz create mode 100644 spec/java_buildpack/framework/takipi_agent_spec.rb diff --git a/README.md b/README.md index 409a8cb32b..a653d75365 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) * [Spring Insight](docs/framework-spring_insight.md) + * [Takipi Agent](docs/framework-takipi_agent.md) ([Configuration](docs/framework-takipi_agent.md#configuration)) * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) * Standard JREs * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 801509f144..4c96331332 100644 --- a/config/components.yml +++ b/config/components.yml @@ -63,5 +63,6 @@ frameworks: - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::YourKitProfiler" + - "JavaBuildpack::Framework::TakipiAgent" - "JavaBuildpack::Framework::SecurityProviders" - "JavaBuildpack::Framework::JavaOpts" diff --git a/config/takipi_agent.yml b/config/takipi_agent.yml new file mode 100644 index 0000000000..e9344046d6 --- /dev/null +++ b/config/takipi_agent.yml @@ -0,0 +1,21 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Takipi framework +--- +version: 4.+ +repository_root: http://get.takipi.com/cloudfoundry +node_name_prefix: node +application_name: diff --git a/docs/framework-takipi_agent.md b/docs/framework-takipi_agent.md new file mode 100644 index 0000000000..a1648ecac3 --- /dev/null +++ b/docs/framework-takipi_agent.md @@ -0,0 +1,49 @@ +# Takipi Agent Framework +The Takipi Agent Framework causes an application to be automatically configured to work with [OverOps Service][]. + +
+ + + + + + +
Detection CriterionExistence of a single bound Takipi service. The existence of an Takipi service defined by the VCAP_SERVICES payload containing a service name, label or tag with app-dynamics or takipi as a substring. +
Tagstakipi-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +When binding Takipi using a user-provided service, it must have name or tag with `takipi` in it. +The credential payload can contain the following entries. + +| Name | Description +| ---- | ----------- +| `secret_key` | (Optional) The agent installation key +| `collector_host` | (Optional) The remote collector hostname or IP +| `collector_port` | (Optional) the remote collector port + +Setting `secret_key` will run a local collector alongside the agent. Setting `collector_host` will use a remote collector. More information can be found in [OverOps Remote Collector][] + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/takipi_agent.yml`][] file. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `node_name_prefix` | Node name prefix, will be concatenated with `-` and instance index +| `application_name` | Override the Cloudfoundry default application name + +## Logs + +Currently, you can get the Takipi agent logs using `cf files` command: +``` +cf files app_name app/.java-buildpack/takipi_agent/log/ +``` + +[`config/takipi_agent.yml`]: ../config/takipi_agent.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering +[OverOps Remote Collector]: https://support.overops.com/hc/en-us/articles/227109628-Remote-Daemon-Process- +[OverOps Service]: https://www.overops.com diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb new file mode 100644 index 0000000000..474613a172 --- /dev/null +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -0,0 +1,104 @@ +# Cloud Foundry Java Buildpack +# +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/qualify_path' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch OverOps (fka Takipi) support. + class TakipiAgent < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_tar + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + java_opts = @droplet.java_opts + java_opts.add_agentpath(@droplet.sandbox + 'lib/libTakipiAgent.so') + application_name java_opts + default_env_vars + credentials = @application.services.find_service(FILTER)['credentials'] + config_env_vars credentials + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, [SECRET_KEY, COLLECTOR_HOST] + end + + private + + FILTER = /takipi/ + + SECRET_KEY = 'secret_key'.freeze + + COLLECTOR_HOST = 'collector_host'.freeze + + private_constant :FILTER + + def jvm_lib_file + @droplet.java_home.root + 'lib/amd64/server/libjvm.so' + end + + def default_env_vars + env = @droplet.environment_variables + sandbox = @droplet.sandbox + + env.add_environment_variable( + 'LD_LIBRARY_PATH', + "$LD_LIBRARY_PATH:#{qualify_path(sandbox + 'lib', @droplet.root)}" + ) + env.add_environment_variable('JVM_LIB_FILE', jvm_lib_file) + env.add_environment_variable('TAKIPI_HOME', sandbox) + env.add_environment_variable('TAKIPI_MACHINE_NAME', node_name) + end + + def config_env_vars(credentials) + env = @droplet.environment_variables + + secret_key = credentials['secret_key'] + env.add_environment_variable 'TAKIPI_SECRET_KEY', secret_key if secret_key + + collector_host = credentials['collector_host'] + env.add_environment_variable 'TAKIPI_MASTER_HOST', collector_host if collector_host + + collector_port = credentials['collector_port'] + env.add_environment_variable 'TAKIPI_MASTER_PORT', collector_port if collector_port + end + + def application_name(java_opts) + app_name = @configuration['application_name'] || @application.details['application_name'] + java_opts.add_system_property('takipi.name', app_name) + end + + def node_name + "#{@configuration['node_name_prefix']}-$CF_INSTANCE_INDEX" + end + + end + + end +end diff --git a/spec/fixtures/stub-takipi-agent.tar.gz b/spec/fixtures/stub-takipi-agent.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..707a6a4e435aefcac4fcfd6eb2bab0131d36dbb7 GIT binary patch literal 1126 zcmV-s1eyCEiwFQqq;6LL1MQv7j@vd6fc+@@0#-y(6nkxf`ltg>ED~qZ~ z1=+W+WDAK6Sxrcf206^PSa^R7jJ+RcNQ$J^t5?&Rce^b~N2Cy!$D%ktrdfV@ys%@L zZn@}6(hp`^lS2uz|wzhoGKeVw*&80^=KIg z_b-Lyix!P^Z$82UkU(<5i$SE81?@sEd77I3TEYO93(CzntcOD6IMKRQ0NkFsncj^`UUo}7@h^YVL2l>a~j{ouR0k-sWCSv@@X#F3Dd;V<)8zbC* zE_3pa!oq)ITI2V%E{$q|Vnp=+ET{QD3M>An<$r5|V#JL9sQ%-y;=g~^P*?w=`u{>u z{-dzs-wh6K2WW(UnbP2dQjDOnyhr|E-hZzTi z`F#B&z`E#BBEjW$;Fu3wRe*R%A`@xQRue_NK0NaE;oc(d*KSA{$g{A+$ylJ4! zUkLXvL_y;}6qf$~{`fnr{uuu}rS)GFZvA(?^|l-iQv>(~EJlR?g7*L7aO>aw+ZeB3 z>arSJ09cF&|1zWfzbM@L|MUFauhZ@yzy=U8{!3FD|Dmwz|NW`+Z!nD@V*a0IH2y>3 zp8wx^Qy(>40f@+dmQ(+a!j=Et|KkR*MV~9e{paWFKjeRVuKc@B^{$?)PGL? zQJDRY@6Nk=qXA%e{pXxf{YT-}|K+BC$%_Mx5uX2o(fkjGTmReq8-SSc-?aae@_&1l z{=eM@Wc&%podCnfe`&@k|55m!e~4p%;q_liM&myezVH9>yTL^G7diPy;nx3r*S~Q9 sXrXTYvWwgQNBjSAxb=T|fQ}LFKNp literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/takipi_agent_spec.rb b/spec/java_buildpack/framework/takipi_agent_spec.rb new file mode 100644 index 0000000000..ddc80c9872 --- /dev/null +++ b/spec/java_buildpack/framework/takipi_agent_spec.rb @@ -0,0 +1,105 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/takipi_agent' +require 'java_buildpack/util/find_single_directory' + +describe JavaBuildpack::Framework::TakipiAgent do + include_context 'component_helper' + + let(:configuration) do + { + 'node_name_prefix' => nil + } + end + + it 'does not detect without takipi-n/a service' do + expect(component.detect).to be_nil + end + + context do + + let(:credentials) { {} } + + before do + allow(services).to receive(:one_service?).with(/takipi/, %w[secret_key collector_host]).and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => credentials) + end + + it 'expands Takipi agent tarball', + cache_fixture: 'stub-takipi-agent.tar.gz' do + + component.compile + + expect(sandbox + 'lib/libTakipiAgent.so').to exist + end + + it 'preserves find_single_directory results', + cache_fixture: 'stub-takipi-agent.tar.gz', + app_fixture: 'container_play_2.1_dist' do + component.compile + component.send(:extend, JavaBuildpack::Util) + expect(component.send(:find_single_directory)).not_to be_nil + end + + context do + let(:credentials) { { 'collector_host' => 'test-host' } } + + it 'updates default environment variables' do + component.release + + expect(environment_variables) + .to include('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/.java-buildpack/takipi_agent/lib') + expect(environment_variables).to include('JVM_LIB_FILE=$PWD/.test-java-home/lib/amd64/server/libjvm.so') + expect(environment_variables).to include('TAKIPI_HOME=$PWD/.java-buildpack/takipi_agent') + end + + it 'updates user environment variables' do + component.release + + expect(environment_variables).to include('TAKIPI_MASTER_HOST=test-host') + end + + context 'secret key' do + let(:credentials) { super().merge 'secret_key' => 'test-key' } + + it 'secret key set' do + component.release + + expect(environment_variables).to include('TAKIPI_SECRET_KEY=test-key') + end + end + + context 'configuration overrides' do + + let(:configuration) do + { 'node_name_prefix' => 'test-name', + 'application_name' => 'test-name' } + end + + it 'update application name' do + component.release + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/takipi_agent/lib/libTakipiAgent.so') + expect(java_opts).to include('-Dtakipi.name=test-name') + end + + end + end + + end + +end From 6b00ecdbf54bf5d5aa42d131e386d3dd6dbe77ae Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Aug 2017 12:13:37 -0700 Subject: [PATCH 340/812] Polishing This change includes some minor polishing to match project conventions [#472] --- .idea/dictionaries/bhale.xml | 2 + config/takipi_agent.yml | 2 +- lib/java_buildpack/framework/takipi_agent.rb | 50 +++++++++---------- rakelib/versions_task.rb | 1 + .../framework/takipi_agent_spec.rb | 24 +++------ 5 files changed, 35 insertions(+), 44 deletions(-) diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 7af11507f1..42f7cc42eb 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -49,6 +49,7 @@ libcklog libcrpytoki libcryptoki + libjvm libruxitagentloader libyjpagent ljust @@ -99,6 +100,7 @@ stubframework stubjre submodules + takipi tasklib teamserver tenanttoken diff --git a/config/takipi_agent.yml b/config/takipi_agent.yml index e9344046d6..6f3e2cc1fd 100644 --- a/config/takipi_agent.yml +++ b/config/takipi_agent.yml @@ -18,4 +18,4 @@ version: 4.+ repository_root: http://get.takipi.com/cloudfoundry node_name_prefix: node -application_name: +application_name: diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index 474613a172..3651b87da6 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -34,12 +34,18 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - java_opts = @droplet.java_opts - java_opts.add_agentpath(@droplet.sandbox + 'lib/libTakipiAgent.so') - application_name java_opts - default_env_vars - credentials = @application.services.find_service(FILTER)['credentials'] - config_env_vars credentials + @droplet.java_opts + .add_agentpath(agent) + .add_system_property('takipi.name', application_name) + + @droplet.environment_variables + .add_environment_variable('LD_LIBRARY_PATH', + "$LD_LIBRARY_PATH:#{qualify_path(lib, @droplet.root)}") + .add_environment_variable('JVM_LIB_FILE', libjvm) + .add_environment_variable('TAKIPI_HOME', @droplet.sandbox) + .add_environment_variable('TAKIPI_MACHINE_NAME', node_name) + + config_env_vars @application.services.find_service(FILTER)['credentials'] end protected @@ -51,29 +57,20 @@ def supports? private + COLLECTOR_HOST = 'collector_host'.freeze + FILTER = /takipi/ SECRET_KEY = 'secret_key'.freeze - COLLECTOR_HOST = 'collector_host'.freeze + private_constant :COLLECTOR_HOST, :FILTER, :SECRET_KEY - private_constant :FILTER - - def jvm_lib_file - @droplet.java_home.root + 'lib/amd64/server/libjvm.so' + def agent + @droplet.sandbox + 'lib/libTakipiAgent.so' end - def default_env_vars - env = @droplet.environment_variables - sandbox = @droplet.sandbox - - env.add_environment_variable( - 'LD_LIBRARY_PATH', - "$LD_LIBRARY_PATH:#{qualify_path(sandbox + 'lib', @droplet.root)}" - ) - env.add_environment_variable('JVM_LIB_FILE', jvm_lib_file) - env.add_environment_variable('TAKIPI_HOME', sandbox) - env.add_environment_variable('TAKIPI_MACHINE_NAME', node_name) + def application_name + @configuration['application_name'] || @application.details['application_name'] end def config_env_vars(credentials) @@ -89,9 +86,12 @@ def config_env_vars(credentials) env.add_environment_variable 'TAKIPI_MASTER_PORT', collector_port if collector_port end - def application_name(java_opts) - app_name = @configuration['application_name'] || @application.details['application_name'] - java_opts.add_system_property('takipi.name', app_name) + def lib + @droplet.sandbox + 'lib' + end + + def libjvm + @droplet.java_home.root + 'lib/amd64/server/libjvm.so' end def node_name diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index f8a7ac523a..cea7973d18 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -81,6 +81,7 @@ def initialize 'redis_store' => 'Redis Session Store', 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', 'spring_boot_cli' => 'Spring Boot CLI', + 'takipi_agent' => 'Takipi Agent', 'tomcat' => 'Tomcat', 'your_kit_profiler' => 'YourKit Profiler' }.freeze diff --git a/spec/java_buildpack/framework/takipi_agent_spec.rb b/spec/java_buildpack/framework/takipi_agent_spec.rb index ddc80c9872..333b9405df 100644 --- a/spec/java_buildpack/framework/takipi_agent_spec.rb +++ b/spec/java_buildpack/framework/takipi_agent_spec.rb @@ -16,16 +16,11 @@ require 'spec_helper' require 'component_helper' require 'java_buildpack/framework/takipi_agent' -require 'java_buildpack/util/find_single_directory' describe JavaBuildpack::Framework::TakipiAgent do include_context 'component_helper' - let(:configuration) do - { - 'node_name_prefix' => nil - } - end + let(:configuration) { { 'node_name_prefix' => nil } } it 'does not detect without takipi-n/a service' do expect(component.detect).to be_nil @@ -40,6 +35,10 @@ allow(services).to receive(:find_service).and_return('credentials' => credentials) end + it 'detects with takipi service' do + expect(component.detect).to eq("takipi-agent=#{version}") + end + it 'expands Takipi agent tarball', cache_fixture: 'stub-takipi-agent.tar.gz' do @@ -48,14 +47,6 @@ expect(sandbox + 'lib/libTakipiAgent.so').to exist end - it 'preserves find_single_directory results', - cache_fixture: 'stub-takipi-agent.tar.gz', - app_fixture: 'container_play_2.1_dist' do - component.compile - component.send(:extend, JavaBuildpack::Util) - expect(component.send(:find_single_directory)).not_to be_nil - end - context do let(:credentials) { { 'collector_host' => 'test-host' } } @@ -86,10 +77,7 @@ context 'configuration overrides' do - let(:configuration) do - { 'node_name_prefix' => 'test-name', - 'application_name' => 'test-name' } - end + let(:configuration) { { 'node_name_prefix' => 'test-name', 'application_name' => 'test-name' } } it 'update application name' do component.release From e5c659f1ef01b4ab3cd2b90fd924d67159db0529 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 10 Aug 2017 09:52:05 -0700 Subject: [PATCH 341/812] Handle Directories Ending in .jar Currently, if the artifact being staged has directories ending in .jar they are treated as archives unconditionally, causing error messages. This changes causes the directories to be treated as they are, rather than artifacts. [resolves #478] --- lib/java_buildpack/framework/jrebel_agent.rb | 4 +++- .../jre/open_jdk_like_memory_calculator.rb | 3 ++- .../dependency.jar/.gitkeep | 0 .../dependency.jar/.gitkeep | 0 spec/java_buildpack/framework/jrebel_agent_spec.rb | 13 +++++++++++-- .../jre/open_jdk_like_memory_calculator_spec.rb | 9 +++++++++ 6 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 spec/fixtures/framework_jrebel_jar_directory/dependency.jar/.gitkeep create mode 100644 spec/fixtures/jre_memory_calculator_jar_directory/dependency.jar/.gitkeep diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index ad8ddf9b0f..27816b2efb 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -59,7 +59,9 @@ def jrebel_configured?(root_path) end def jars_with_jrebel_configured?(root_path) - (root_path + '**/*.jar').glob.any? { |jar| !`unzip -l "#{jar}" | grep "rebel-remote\\.xml$"`.strip.empty? } + (root_path + '**/*.jar') + .glob.reject(&:directory?) + .any? { |jar| !`unzip -l "#{jar}" | grep "rebel-remote\\.xml$"`.strip.empty? } end def lib_name diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index bbb65b75dd..54e37ff7ec 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -71,7 +71,8 @@ def supports? def actual_class_count(root) (root + '**/*.class').glob.count + (root + '**/*.groovy').glob.count + - (root + '**/*.jar').glob(File::FNM_DOTMATCH).inject(0) { |a, e| a + archive_class_count(e) } + (root + '**/*.jar').glob(File::FNM_DOTMATCH).reject(&:directory?) + .inject(0) { |a, e| a + archive_class_count(e) } end def archive_class_count(archive) diff --git a/spec/fixtures/framework_jrebel_jar_directory/dependency.jar/.gitkeep b/spec/fixtures/framework_jrebel_jar_directory/dependency.jar/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/jre_memory_calculator_jar_directory/dependency.jar/.gitkeep b/spec/fixtures/jre_memory_calculator_jar_directory/dependency.jar/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb index c6f91b223b..de55c96917 100644 --- a/spec/java_buildpack/framework/jrebel_agent_spec.rb +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -44,12 +44,13 @@ it 'does not detect when not enabled', app_fixture: 'framework_jrebel_app_simple' do + expect(component.detect).to be_nil end end it 'downloads the JRebel JAR and the native agent', - app_fixture: 'framework_jrebel_app_simple', + app_fixture: 'framework_jrebel_app_simple', cache_fixture: 'stub-jrebel-archive.zip' do component.compile @@ -59,7 +60,7 @@ end it 'adds correct arguments to JAVA_OPTS', - app_fixture: 'framework_jrebel_app_simple', + app_fixture: 'framework_jrebel_app_simple', cache_fixture: 'stub-jrebel-archive.zip' do allow(component).to receive(:architecture).and_return('x86_64') @@ -71,4 +72,12 @@ expect(java_opts).to include('-Drebel.cloud.platform=cloudfoundry/java-buildpack') end + it 'does not throw an error when a directory ends in .jar', + app_fixture: 'framework_jrebel_jar_directory' do + + expect_any_instance_of(described_class).not_to receive(:`).with(start_with("unzip -l #{app_dir + 'directory.jar'}")) + + component.detect + end + end diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 3b59d4b31b..200aa7014a 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -88,4 +88,13 @@ 'Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') end + it 'does not throw an error when a directory ends in .jar', + app_fixture: 'jre_memory_calculator_jar_directory', + cache_fixture: 'stub-memory-calculator.tar.gz' do + + expect_any_instance_of(described_class).not_to receive(:`).with(start_with("unzip -l #{app_dir + 'directory.jar'}")) + + component.compile + end + end From 7a7b3af4d56145ef38c65c8133ba1c2173501fdb Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 20 Jun 2017 12:13:43 -0700 Subject: [PATCH 342/812] Colorize Output This change adds some color to the staging output. Specifically it highlights the component names, versions, and download times to make them more apparent in logs. Note this is a first attempt and the color scheme may be updated as better alternatives are found. --- lib/java_buildpack/buildpack.rb | 3 +- lib/java_buildpack/buildpack_version.rb | 6 +- .../component/base_component.rb | 7 +- lib/java_buildpack/util/colorize.rb | 102 ++++++++++++++++++ 4 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 lib/java_buildpack/util/colorize.rb diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 7d6d28e84b..b7183f2ca9 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -25,6 +25,7 @@ require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/component/security_providers' require 'java_buildpack/logging/logger_factory' +require 'java_buildpack/util/colorize' require 'java_buildpack/util/configuration_utils' require 'java_buildpack/util/constantize' require 'java_buildpack/util/snake_case' @@ -100,7 +101,7 @@ def release private - BUILDPACK_MESSAGE = '-----> Java Buildpack Version: %s'.freeze + BUILDPACK_MESSAGE = "#{'----->'.red.bold} #{'Java Buildpack'.blue.bold} %s".freeze LOAD_ROOT = (Pathname.new(__FILE__).dirname + '..').freeze diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index cab64e96c7..1bc8d9dc1e 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -83,15 +83,15 @@ def to_hash # @return [String] a +String+ representation of the version def to_s(human_readable = true) s = [] - s << @version if @version - s << (human_readable ? '(offline)' : 'offline') if @offline + s << @version.blue if @version + s << (human_readable ? '(offline)'.blue : 'offline') if @offline if remote_string s << '|' if @version && human_readable s << remote_string end - s << 'unknown' if s.empty? + s << 'unknown'.yellow if s.empty? s.join(human_readable ? ' ' : '-') end diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 719f231ce5..2aca2a40f7 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -16,6 +16,7 @@ require 'fileutils' require 'java_buildpack/component' require 'java_buildpack/util/cache/application_cache' +require 'java_buildpack/util/colorize' require 'java_buildpack/util/format_duration' require 'java_buildpack/util/shell' require 'java_buildpack/util/space_case' @@ -86,10 +87,10 @@ def release # @return [Void] def download(version, uri, name = @component_name) download_start_time = Time.now - print "-----> Downloading #{name} #{version} from #{uri.sanitize_uri} " + print "#{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri.sanitize_uri} " JavaBuildpack::Util::Cache::ApplicationCache.new.get(uri) do |file, downloaded| - puts downloaded ? "(#{(Time.now - download_start_time).duration})" : '(found in cache)' + puts downloaded ? "(#{(Time.now - download_start_time).duration})".green.italic : '(found in cache)'.green.italic yield file end end @@ -167,7 +168,7 @@ def with_timing(caption) yield - puts "(#{(Time.now - start_time).duration})" + puts "(#{(Time.now - start_time).duration})".green.italic end private diff --git a/lib/java_buildpack/util/colorize.rb b/lib/java_buildpack/util/colorize.rb new file mode 100644 index 0000000000..184ef35de9 --- /dev/null +++ b/lib/java_buildpack/util/colorize.rb @@ -0,0 +1,102 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +class String + + def bg_black + "\e[40m#{self}\e[0m" + end + + def bg_blue + "\e[44m#{self}\e[0m" + end + + def bg_brown + "\e[43m#{self}\e[0m" + end + + def bg_cyan + "\e[46m#{self}\e[0m" + end + + def bg_gray + "\e[47m#{self}\e[0m" + end + + def bg_green + "\e[42m#{self}\e[0m" + end + + def bg_magenta + "\e[45m#{self}\e[0m" + end + + def bg_red + "\e[41m#{self}\e[0m" + end + + def black + "\e[30m#{self}\e[0m" + end + + def blink + "\e[5m#{self}\e[25m" + end + + def blue + "\e[34m#{self}\e[0m" + end + + def bold + "\e[1m#{self}\e[22m" + end + + def brown + "\e[33m#{self}\e[0m" + end + + def cyan + "\e[36m#{self}\e[0m" + end + + def gray + "\e[37m#{self}\e[0m" + end + + def green + "\e[32m#{self}\e[0m" + end + + def italic + "\e[3m#{self}\e[23m" + end + + def magenta + "\e[35m#{self}\e[0m" + end + + def red + "\e[31m#{self}\e[0m" + end + + def reverse_color + "\e[7m#{self}\e[27m" + end + + def underline + "\e[4m#{self}\e[24m" + end + +end \ No newline at end of file From c09cb3806fb7a89c8d533b2432e0aacb5f8914b7 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 14 Aug 2017 15:28:42 -0700 Subject: [PATCH 343/812] Revert "Colorize Output" This reverts commit 7a7b3af4d56145ef38c65c8133ba1c2173501fdb. --- lib/java_buildpack/buildpack.rb | 3 +- lib/java_buildpack/buildpack_version.rb | 6 +- .../component/base_component.rb | 7 +- lib/java_buildpack/util/colorize.rb | 102 ------------------ 4 files changed, 7 insertions(+), 111 deletions(-) delete mode 100644 lib/java_buildpack/util/colorize.rb diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index b7183f2ca9..7d6d28e84b 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -25,7 +25,6 @@ require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/component/security_providers' require 'java_buildpack/logging/logger_factory' -require 'java_buildpack/util/colorize' require 'java_buildpack/util/configuration_utils' require 'java_buildpack/util/constantize' require 'java_buildpack/util/snake_case' @@ -101,7 +100,7 @@ def release private - BUILDPACK_MESSAGE = "#{'----->'.red.bold} #{'Java Buildpack'.blue.bold} %s".freeze + BUILDPACK_MESSAGE = '-----> Java Buildpack Version: %s'.freeze LOAD_ROOT = (Pathname.new(__FILE__).dirname + '..').freeze diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index 1bc8d9dc1e..cab64e96c7 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -83,15 +83,15 @@ def to_hash # @return [String] a +String+ representation of the version def to_s(human_readable = true) s = [] - s << @version.blue if @version - s << (human_readable ? '(offline)'.blue : 'offline') if @offline + s << @version if @version + s << (human_readable ? '(offline)' : 'offline') if @offline if remote_string s << '|' if @version && human_readable s << remote_string end - s << 'unknown'.yellow if s.empty? + s << 'unknown' if s.empty? s.join(human_readable ? ' ' : '-') end diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 2aca2a40f7..719f231ce5 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -16,7 +16,6 @@ require 'fileutils' require 'java_buildpack/component' require 'java_buildpack/util/cache/application_cache' -require 'java_buildpack/util/colorize' require 'java_buildpack/util/format_duration' require 'java_buildpack/util/shell' require 'java_buildpack/util/space_case' @@ -87,10 +86,10 @@ def release # @return [Void] def download(version, uri, name = @component_name) download_start_time = Time.now - print "#{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri.sanitize_uri} " + print "-----> Downloading #{name} #{version} from #{uri.sanitize_uri} " JavaBuildpack::Util::Cache::ApplicationCache.new.get(uri) do |file, downloaded| - puts downloaded ? "(#{(Time.now - download_start_time).duration})".green.italic : '(found in cache)'.green.italic + puts downloaded ? "(#{(Time.now - download_start_time).duration})" : '(found in cache)' yield file end end @@ -168,7 +167,7 @@ def with_timing(caption) yield - puts "(#{(Time.now - start_time).duration})".green.italic + puts "(#{(Time.now - start_time).duration})" end private diff --git a/lib/java_buildpack/util/colorize.rb b/lib/java_buildpack/util/colorize.rb deleted file mode 100644 index 184ef35de9..0000000000 --- a/lib/java_buildpack/util/colorize.rb +++ /dev/null @@ -1,102 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -class String - - def bg_black - "\e[40m#{self}\e[0m" - end - - def bg_blue - "\e[44m#{self}\e[0m" - end - - def bg_brown - "\e[43m#{self}\e[0m" - end - - def bg_cyan - "\e[46m#{self}\e[0m" - end - - def bg_gray - "\e[47m#{self}\e[0m" - end - - def bg_green - "\e[42m#{self}\e[0m" - end - - def bg_magenta - "\e[45m#{self}\e[0m" - end - - def bg_red - "\e[41m#{self}\e[0m" - end - - def black - "\e[30m#{self}\e[0m" - end - - def blink - "\e[5m#{self}\e[25m" - end - - def blue - "\e[34m#{self}\e[0m" - end - - def bold - "\e[1m#{self}\e[22m" - end - - def brown - "\e[33m#{self}\e[0m" - end - - def cyan - "\e[36m#{self}\e[0m" - end - - def gray - "\e[37m#{self}\e[0m" - end - - def green - "\e[32m#{self}\e[0m" - end - - def italic - "\e[3m#{self}\e[23m" - end - - def magenta - "\e[35m#{self}\e[0m" - end - - def red - "\e[31m#{self}\e[0m" - end - - def reverse_color - "\e[7m#{self}\e[27m" - end - - def underline - "\e[4m#{self}\e[24m" - end - -end \ No newline at end of file From c6d7eaed388b6aaace144099e3c829784db1475a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 20 Jun 2017 12:13:43 -0700 Subject: [PATCH 344/812] Colorize Output This change adds some color to the staging output. Specifically it highlights the component names, versions, and download times to make them more apparent in logs. Note this is a first attempt and the color scheme may be updated as better alternatives are found. --- lib/java_buildpack/buildpack.rb | 3 +- lib/java_buildpack/buildpack_version.rb | 6 +- .../component/base_component.rb | 7 +- lib/java_buildpack/util/colorize.rb | 102 ++++++++++++++++++ 4 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 lib/java_buildpack/util/colorize.rb diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 7d6d28e84b..b7183f2ca9 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -25,6 +25,7 @@ require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/component/security_providers' require 'java_buildpack/logging/logger_factory' +require 'java_buildpack/util/colorize' require 'java_buildpack/util/configuration_utils' require 'java_buildpack/util/constantize' require 'java_buildpack/util/snake_case' @@ -100,7 +101,7 @@ def release private - BUILDPACK_MESSAGE = '-----> Java Buildpack Version: %s'.freeze + BUILDPACK_MESSAGE = "#{'----->'.red.bold} #{'Java Buildpack'.blue.bold} %s".freeze LOAD_ROOT = (Pathname.new(__FILE__).dirname + '..').freeze diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index cab64e96c7..1bc8d9dc1e 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -83,15 +83,15 @@ def to_hash # @return [String] a +String+ representation of the version def to_s(human_readable = true) s = [] - s << @version if @version - s << (human_readable ? '(offline)' : 'offline') if @offline + s << @version.blue if @version + s << (human_readable ? '(offline)'.blue : 'offline') if @offline if remote_string s << '|' if @version && human_readable s << remote_string end - s << 'unknown' if s.empty? + s << 'unknown'.yellow if s.empty? s.join(human_readable ? ' ' : '-') end diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 719f231ce5..2aca2a40f7 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -16,6 +16,7 @@ require 'fileutils' require 'java_buildpack/component' require 'java_buildpack/util/cache/application_cache' +require 'java_buildpack/util/colorize' require 'java_buildpack/util/format_duration' require 'java_buildpack/util/shell' require 'java_buildpack/util/space_case' @@ -86,10 +87,10 @@ def release # @return [Void] def download(version, uri, name = @component_name) download_start_time = Time.now - print "-----> Downloading #{name} #{version} from #{uri.sanitize_uri} " + print "#{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri.sanitize_uri} " JavaBuildpack::Util::Cache::ApplicationCache.new.get(uri) do |file, downloaded| - puts downloaded ? "(#{(Time.now - download_start_time).duration})" : '(found in cache)' + puts downloaded ? "(#{(Time.now - download_start_time).duration})".green.italic : '(found in cache)'.green.italic yield file end end @@ -167,7 +168,7 @@ def with_timing(caption) yield - puts "(#{(Time.now - start_time).duration})" + puts "(#{(Time.now - start_time).duration})".green.italic end private diff --git a/lib/java_buildpack/util/colorize.rb b/lib/java_buildpack/util/colorize.rb new file mode 100644 index 0000000000..184ef35de9 --- /dev/null +++ b/lib/java_buildpack/util/colorize.rb @@ -0,0 +1,102 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +class String + + def bg_black + "\e[40m#{self}\e[0m" + end + + def bg_blue + "\e[44m#{self}\e[0m" + end + + def bg_brown + "\e[43m#{self}\e[0m" + end + + def bg_cyan + "\e[46m#{self}\e[0m" + end + + def bg_gray + "\e[47m#{self}\e[0m" + end + + def bg_green + "\e[42m#{self}\e[0m" + end + + def bg_magenta + "\e[45m#{self}\e[0m" + end + + def bg_red + "\e[41m#{self}\e[0m" + end + + def black + "\e[30m#{self}\e[0m" + end + + def blink + "\e[5m#{self}\e[25m" + end + + def blue + "\e[34m#{self}\e[0m" + end + + def bold + "\e[1m#{self}\e[22m" + end + + def brown + "\e[33m#{self}\e[0m" + end + + def cyan + "\e[36m#{self}\e[0m" + end + + def gray + "\e[37m#{self}\e[0m" + end + + def green + "\e[32m#{self}\e[0m" + end + + def italic + "\e[3m#{self}\e[23m" + end + + def magenta + "\e[35m#{self}\e[0m" + end + + def red + "\e[31m#{self}\e[0m" + end + + def reverse_color + "\e[7m#{self}\e[27m" + end + + def underline + "\e[4m#{self}\e[24m" + end + +end \ No newline at end of file From bb76ea84fbc409153eaddcd6e3bb0e40ce458a28 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 15 Aug 2017 09:46:47 -0700 Subject: [PATCH 345/812] Colorize Output This change adds some color to the staging output. Specifically it highlights the component names, versions, and download times to make them more apparent in logs. Note this is a first attempt and the color scheme may be updated as better alternatives are found. --- lib/java_buildpack/buildpack_version.rb | 1 + .../component/base_component.rb | 7 +- lib/java_buildpack/util/colorize.rb | 128 ++++++++++++------ spec/console_helper.rb | 3 + spec/java_buildpack/buildpack_version_spec.rb | 1 + 5 files changed, 99 insertions(+), 41 deletions(-) diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index 1bc8d9dc1e..c2bedc3f52 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -14,6 +14,7 @@ # limitations under the License. require 'java_buildpack' +require 'java_buildpack/util/colorize' require 'java_buildpack/util/configuration_utils' require 'java_buildpack/util/to_b' diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 2aca2a40f7..fcac2f7951 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -90,7 +90,12 @@ def download(version, uri, name = @component_name) print "#{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri.sanitize_uri} " JavaBuildpack::Util::Cache::ApplicationCache.new.get(uri) do |file, downloaded| - puts downloaded ? "(#{(Time.now - download_start_time).duration})".green.italic : '(found in cache)'.green.italic + if downloaded + puts "(#{(Time.now - download_start_time).duration})".green.italic + else + puts '(found in cache)'.green.italic + end + yield file end end diff --git a/lib/java_buildpack/util/colorize.rb b/lib/java_buildpack/util/colorize.rb index 184ef35de9..b3911c0aea 100644 --- a/lib/java_buildpack/util/colorize.rb +++ b/lib/java_buildpack/util/colorize.rb @@ -15,88 +15,136 @@ class String - def bg_black - "\e[40m#{self}\e[0m" + @color_enabled = true + + class << self + attr_accessor :color_enabled end - def bg_blue - "\e[44m#{self}\e[0m" + # Sets the string to bold + def bold + return self unless @color_enabled + "\e[1m#{self}\e[22m" end - def bg_brown - "\e[43m#{self}\e[0m" + # Sets the string to italic + def italic + return self unless @color_enabled + "\e[3m#{self}\e[23m" end - def bg_cyan - "\e[46m#{self}\e[0m" + # Sets the string to underlined + def underline + return self unless @color_enabled + "\e[4m#{self}\e[24m" end - def bg_gray - "\e[47m#{self}\e[0m" + # Sets the string to blink + def blink + return self unless @color_enabled + "\e[5m#{self}\e[25m" end - def bg_green - "\e[42m#{self}\e[0m" + # Sets the string reverse the current colors + def reverse_color + return self unless @color_enabled + "\e[7m#{self}\e[27m" end - def bg_magenta - "\e[45m#{self}\e[0m" + # Sets the string to black + def black + return self unless @color_enabled + "\e[30m#{self}\e[0m" end - def bg_red - "\e[41m#{self}\e[0m" + # Sets the string to red + def red + return self unless @color_enabled + "\e[31m#{self}\e[0m" end - def black - "\e[30m#{self}\e[0m" + # Sets the string to green + def green + return self unless @color_enabled + "\e[32m#{self}\e[0m" end - def blink - "\e[5m#{self}\e[25m" + # Sets the string to yellow + def yellow + return self unless @color_enabled + "\e[33m#{self}\e[0m" end + # Sets the string to blue def blue + return self unless @color_enabled "\e[34m#{self}\e[0m" end - def bold - "\e[1m#{self}\e[22m" - end - - def brown - "\e[33m#{self}\e[0m" + # Sets the string to magenta + def magenta + return self unless @color_enabled + "\e[35m#{self}\e[0m" end + # Sets the string to cyan def cyan + return self unless @color_enabled "\e[36m#{self}\e[0m" end - def gray + # Sets the string to white + def white + return self unless @color_enabled "\e[37m#{self}\e[0m" end - def green - "\e[32m#{self}\e[0m" + # Sets the string background to black + def bg_black + return self unless @color_enabled + "\e[40m#{self}\e[0m" end - def italic - "\e[3m#{self}\e[23m" + # Sets the string background to red + def bg_red + return self unless @color_enabled + "\e[41m#{self}\e[0m" end - def magenta - "\e[35m#{self}\e[0m" + # Sets the string background to green + def bg_green + return self unless @color_enabled + "\e[42m#{self}\e[0m" end - def red - "\e[31m#{self}\e[0m" + # Sets the string background to yellow + def bg_yellow + return self unless @color_enabled + "\e[43m#{self}\e[0m" end - def reverse_color - "\e[7m#{self}\e[27m" + # Sets the string background to blue + def bg_blue + return self unless @color_enabled + "\e[44m#{self}\e[0m" end - def underline - "\e[4m#{self}\e[24m" + # Sets the string background to magenta + def bg_magenta + return self unless @color_enabled + "\e[45m#{self}\e[0m" + end + + # Sets the string background to cyan + def bg_cyan + return self unless @color_enabled + "\e[46m#{self}\e[0m" + end + + # Sets the string background to white + def bg_white + return self unless @color_enabled + "\e[47m#{self}\e[0m" end -end \ No newline at end of file +end diff --git a/spec/console_helper.rb b/spec/console_helper.rb index 5c5c6b289c..75f921f735 100644 --- a/spec/console_helper.rb +++ b/spec/console_helper.rb @@ -15,6 +15,7 @@ require 'spec_helper' require 'tee' +require 'java_buildpack/util/colorize' shared_context 'console_helper' do @@ -32,6 +33,8 @@ $stdout.add STDOUT $stderr.add STDERR end + + String.color_enabled = false end after do diff --git a/spec/java_buildpack/buildpack_version_spec.rb b/spec/java_buildpack/buildpack_version_spec.rb index bd2f297af3..b4bc723a3d 100644 --- a/spec/java_buildpack/buildpack_version_spec.rb +++ b/spec/java_buildpack/buildpack_version_spec.rb @@ -21,6 +21,7 @@ describe JavaBuildpack::BuildpackVersion do include_context 'application_helper' + include_context 'console_helper' include_context 'logging_helper' let(:buildpack_version) { described_class.new } From 14837c510fab252bbc33a713cd2a3ddc68a8366b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 15 Aug 2017 09:55:08 -0700 Subject: [PATCH 346/812] Polishing --- lib/java_buildpack/jre/ibm_jre_initializer.rb | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/lib/java_buildpack/jre/ibm_jre_initializer.rb b/lib/java_buildpack/jre/ibm_jre_initializer.rb index e7c28d4a7a..b4ae8b9bd0 100644 --- a/lib/java_buildpack/jre/ibm_jre_initializer.rb +++ b/lib/java_buildpack/jre/ibm_jre_initializer.rb @@ -75,11 +75,6 @@ def release private_constant :HEAP_RATIO, :KILO - # Installs the Downloaded InstallAnywhere (tm) BIN file to the target directory - # - # @param [String] target_directory, Where the java needs to be installed - # @param [File] file, InstallAnywhere (tm) BIN file - # @return [Void] def install_bin(target_directory, file) FileUtils.mkdir_p target_directory response_file = Tempfile.new('response.properties') @@ -92,7 +87,6 @@ def install_bin(target_directory, file) shell "#{file.path} -i silent -f #{response_file.path} 2>&1" end - # Returns the max heap size ('-Xmx') value def mem_opts mopts = [] total_memory = memory_limit_finder @@ -106,12 +100,10 @@ def mem_opts mopts end - # Returns the heap_ratio attribute in config file (if specified) or the HEAP_RATIO constant value def heap_ratio @configuration['heap_ratio'] || HEAP_RATIO end - # Returns the container total memory limit in bytes def memory_limit_finder memory_limit = ENV['MEMORY_LIMIT'] return nil unless memory_limit @@ -120,10 +112,6 @@ def memory_limit_finder memory_limit_size end - # Returns the no. of bytes for a given string of minified size representation - # - # @param [String] size, A minified memory representation string - # @return [Integer] bytes, value of size in bytes def memory_size_bytes(size) if size == '0' bytes = 0 @@ -139,11 +127,6 @@ def memory_size_bytes(size) bytes end - # Returns the no. of bytes for a given memory size unit - # - # @param [String] unit, Represents a Memory Size Unit - # @param [Integer] value - # @return [Integer] bytes, value of size in bytes def calculate_bytes(unit, value) if %w[b B].include?(unit) bytes = value @@ -159,25 +142,15 @@ def calculate_bytes(unit, value) bytes end - # Checks whether the given value is an Integer - # - # @param [String] v, value as a string def check_is_integer?(v) v = Float(v) v && v.floor == v end - # Calculates the Heap size as per the Heap ratio - # - # @param [Integer] membytes, total memory in bytes - # @param [Numeric] heapratio, Desired/Default Heap Ratio def heap_size_calculator(membytes, heapratio) memory_size_minified(membytes * heapratio) end - # Calculates the Memory Size in a Minified String Representation - # - # @param [Numeric] membytes, calculated heap size def memory_size_minified(membytes) giga = membytes / 2**(10 * 3) mega = membytes / 2**(10 * 2) @@ -191,16 +164,10 @@ def memory_size_minified(membytes) end end - # Returns the minified memory string - # - # @param [Integer] order, calculated memory value - # @param [String] char, calculated memory unit - # @return [String] minified memory string def minified_size_calculator(order, char) order.to_i.to_s + char end - # Verifies whether heap ratio is valid def heap_ratio_verification(ratio) raise 'Invalid heap ratio' unless ratio.is_a? Numeric raise 'heap ratio cannot be greater than 100%' unless ratio <= 1 From 181dbf9e2be75410695172ffd6a2f5924ae57228 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 15 Aug 2017 10:26:33 -0700 Subject: [PATCH 347/812] Finish Colorize Previous attempts at colorization had a bug that meant that it didn't actually colorize anything. This change causes colors to be emitted. Sloppy work all around. --- lib/java_buildpack/util/colorize.rb | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/java_buildpack/util/colorize.rb b/lib/java_buildpack/util/colorize.rb index b3911c0aea..4e777449a9 100644 --- a/lib/java_buildpack/util/colorize.rb +++ b/lib/java_buildpack/util/colorize.rb @@ -23,127 +23,127 @@ class << self # Sets the string to bold def bold - return self unless @color_enabled + return self unless self.class.color_enabled "\e[1m#{self}\e[22m" end # Sets the string to italic def italic - return self unless @color_enabled + return self unless self.class.color_enabled "\e[3m#{self}\e[23m" end # Sets the string to underlined def underline - return self unless @color_enabled + return self unless self.class.color_enabled "\e[4m#{self}\e[24m" end # Sets the string to blink def blink - return self unless @color_enabled + return self unless self.class.color_enabled "\e[5m#{self}\e[25m" end # Sets the string reverse the current colors def reverse_color - return self unless @color_enabled + return self unless self.class.color_enabled "\e[7m#{self}\e[27m" end # Sets the string to black def black - return self unless @color_enabled + return self unless self.class.color_enabled "\e[30m#{self}\e[0m" end # Sets the string to red def red - return self unless @color_enabled + return self unless self.class.color_enabled "\e[31m#{self}\e[0m" end # Sets the string to green def green - return self unless @color_enabled + return self unless self.class.color_enabled "\e[32m#{self}\e[0m" end # Sets the string to yellow def yellow - return self unless @color_enabled + return self unless self.class.color_enabled "\e[33m#{self}\e[0m" end # Sets the string to blue def blue - return self unless @color_enabled + return self unless self.class.color_enabled "\e[34m#{self}\e[0m" end # Sets the string to magenta def magenta - return self unless @color_enabled + return self unless self.class.color_enabled "\e[35m#{self}\e[0m" end # Sets the string to cyan def cyan - return self unless @color_enabled + return self unless self.class.color_enabled "\e[36m#{self}\e[0m" end # Sets the string to white def white - return self unless @color_enabled + return self unless self.class.color_enabled "\e[37m#{self}\e[0m" end # Sets the string background to black def bg_black - return self unless @color_enabled + return self unless self.class.color_enabled "\e[40m#{self}\e[0m" end # Sets the string background to red def bg_red - return self unless @color_enabled + return self unless self.class.color_enabled "\e[41m#{self}\e[0m" end # Sets the string background to green def bg_green - return self unless @color_enabled + return self unless self.class.color_enabled "\e[42m#{self}\e[0m" end # Sets the string background to yellow def bg_yellow - return self unless @color_enabled + return self unless self.class.color_enabled "\e[43m#{self}\e[0m" end # Sets the string background to blue def bg_blue - return self unless @color_enabled + return self unless self.class.color_enabled "\e[44m#{self}\e[0m" end # Sets the string background to magenta def bg_magenta - return self unless @color_enabled + return self unless self.class.color_enabled "\e[45m#{self}\e[0m" end # Sets the string background to cyan def bg_cyan - return self unless @color_enabled + return self unless self.class.color_enabled "\e[46m#{self}\e[0m" end # Sets the string background to white def bg_white - return self unless @color_enabled + return self unless self.class.color_enabled "\e[47m#{self}\e[0m" end From 5275942536afa54806cae4e17b951d614060bbc3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 15 Aug 2017 10:49:23 -0700 Subject: [PATCH 348/812] Polishing This change cleans up some naming to be more consistent with the rest of the code. --- bin/compile | 4 ++-- bin/detect | 4 ++-- bin/release | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/compile b/bin/compile index eb481cfe9e..c2c06cb28d 100755 --- a/bin/compile +++ b/bin/compile @@ -20,6 +20,6 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'java_buildpack/buildpack' -build_dir = ARGV[0] +app_dir = ARGV[0] -JavaBuildpack::Buildpack.with_buildpack(build_dir, 'Compile failed with exception %s', &:compile) +JavaBuildpack::Buildpack.with_buildpack(app_dir, 'Compile failed with exception %s', &:compile) diff --git a/bin/detect b/bin/detect index 9f4dd76d50..54ef35f955 100755 --- a/bin/detect +++ b/bin/detect @@ -20,9 +20,9 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'java_buildpack/buildpack' -build_dir = ARGV[0] +app_dir = ARGV[0] -components = JavaBuildpack::Buildpack.with_buildpack(build_dir, 'Detect failed with exception %s', &:detect).compact +components = JavaBuildpack::Buildpack.with_buildpack(app_dir, 'Detect failed with exception %s', &:detect).compact if components.empty? abort diff --git a/bin/release b/bin/release index 9b9dad0427..02f9b07f6f 100755 --- a/bin/release +++ b/bin/release @@ -20,8 +20,8 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'java_buildpack/buildpack' -build_dir = ARGV[0] +app_dir = ARGV[0] -output = JavaBuildpack::Buildpack.with_buildpack(build_dir, 'Release failed with exception %s', &:release) +output = JavaBuildpack::Buildpack.with_buildpack(app_dir, 'Release failed with exception %s', &:release) puts output From c36c854d3ab50057e31941d7cde8ead41ce181ed Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 16 Aug 2017 08:55:24 -0700 Subject: [PATCH 349/812] Polishing --- spec/java_buildpack/buildpack_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/java_buildpack/buildpack_spec.rb b/spec/java_buildpack/buildpack_spec.rb index ed3cf61b88..c65e26a84b 100644 --- a/spec/java_buildpack/buildpack_spec.rb +++ b/spec/java_buildpack/buildpack_spec.rb @@ -47,9 +47,9 @@ allow(JavaBuildpack::Util::ConfigurationUtils).to receive(:load).and_call_original allow(JavaBuildpack::Util::ConfigurationUtils) .to receive(:load).with('components').and_return( - 'containers' => ['Test::StubContainer1', 'Test::StubContainer2'], - 'frameworks' => ['Test::StubFramework1', 'Test::StubFramework2'], - 'jres' => ['Test::StubJre1', 'Test::StubJre2'] + 'containers' => %w[Test::StubContainer1 Test::StubContainer2], + 'frameworks' => %w[Test::StubFramework1 Test::StubFramework2], + 'jres' => %w[Test::StubJre1 Test::StubJre2] ) allow(Test::StubContainer1).to receive(:new).and_return(stub_container1) From d7fc55a37aea5bda9e8cc296601964d1d7f2bb2b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 16 Aug 2017 08:58:36 -0700 Subject: [PATCH 350/812] Cache Factory This change adds a CacheFactory that will automatically choose the appropriate type of cache based on whether an invocation has access to an application cache location. --- .../component/base_component.rb | 4 +- .../repository/repository_index.rb | 6 +-- .../util/cache/application_cache.rb | 28 +++++++++-- .../util/cache/cache_factory.rb | 48 ++++++++++++++++++ .../util/cache/cache_factory_spec.rb | 49 +++++++++++++++++++ 5 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 lib/java_buildpack/util/cache/cache_factory.rb create mode 100644 spec/java_buildpack/util/cache/cache_factory_spec.rb diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index fcac2f7951..5c744f5c74 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -15,7 +15,7 @@ require 'fileutils' require 'java_buildpack/component' -require 'java_buildpack/util/cache/application_cache' +require 'java_buildpack/util/cache/cache_factory' require 'java_buildpack/util/colorize' require 'java_buildpack/util/format_duration' require 'java_buildpack/util/shell' @@ -89,7 +89,7 @@ def download(version, uri, name = @component_name) download_start_time = Time.now print "#{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri.sanitize_uri} " - JavaBuildpack::Util::Cache::ApplicationCache.new.get(uri) do |file, downloaded| + JavaBuildpack::Util::Cache::CacheFactory.create.get(uri) do |file, downloaded| if downloaded puts "(#{(Time.now - download_start_time).duration})".green.italic else diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 192b79d0cc..a800daba5d 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -16,8 +16,7 @@ require 'java_buildpack/logging/logger_factory' require 'java_buildpack/repository' require 'java_buildpack/repository/version_resolver' -require 'java_buildpack/util/cache' -require 'java_buildpack/util/cache/download_cache' +require 'java_buildpack/util/cache/cache_factory' require 'java_buildpack/util/configuration_utils' require 'rbconfig' require 'yaml' @@ -66,8 +65,7 @@ def architecture end def cache - JavaBuildpack::Util::Cache::DownloadCache.new(Pathname.new(Dir.tmpdir), - JavaBuildpack::Util::Cache::CACHED_RESOURCES_DIRECTORY) + JavaBuildpack::Util::Cache::CacheFactory.create end def canonical(raw) diff --git a/lib/java_buildpack/util/cache/application_cache.rb b/lib/java_buildpack/util/cache/application_cache.rb index 24d55f31c3..cffbba7338 100644 --- a/lib/java_buildpack/util/cache/application_cache.rb +++ b/lib/java_buildpack/util/cache/application_cache.rb @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +require 'java_buildpack/logging/logger_factory' require 'java_buildpack/util/cache' require 'java_buildpack/util/cache/download_cache' @@ -26,11 +27,32 @@ module Cache # WARNING: This cache should only by used by code run by the +compile+ script class ApplicationCache < DownloadCache + class << self + + # Whether an +ApplicationCache+ can be created + # + # @return [Boolean] whether an +ApplicationCache+ can be created + def available? + !application_cache_directory.nil? + end + + # The path to the application cache directory if it exists + # + # @return [void, String] the path to the application cache directory if it exists + def application_cache_directory + ARGV[1] + end + + end + # Creates an instance of the cache that is backed by the the application cache def initialize - application_cache_directory = ARGV[1] - raise 'Application cache directory is undefined' if application_cache_directory.nil? - super(Pathname.new(application_cache_directory), CACHED_RESOURCES_DIRECTORY) + logger = Logging::LoggerFactory.instance.get_logger ApplicationCache + + raise 'Application cache directory is undefined' unless self.class.available? + logger.debug { "Application Cache Directory: #{self.class.application_cache_directory}" } + + super(Pathname.new(self.class.application_cache_directory), CACHED_RESOURCES_DIRECTORY) end end diff --git a/lib/java_buildpack/util/cache/cache_factory.rb b/lib/java_buildpack/util/cache/cache_factory.rb new file mode 100644 index 0000000000..1f00eb2e53 --- /dev/null +++ b/lib/java_buildpack/util/cache/cache_factory.rb @@ -0,0 +1,48 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/util/cache' +require 'java_buildpack/util/cache/application_cache' +require 'java_buildpack/util/cache/download_cache' + +module JavaBuildpack + module Util + module Cache + + # A factory for creating {DownloadCache}s. Will create an {ApplicationCache} if it can, otherwise a + # {DownloadCache}. + class CacheFactory + + class << self + + # Creates a new instance of an {ApplicationCache} if it can, otherwise a {DownloadCache} + # + # @return [ApplicationCache, DownloadCache] a new instance of an {ApplicationCache} if it can, otherwise a + # {DownloadCache} + def create + if ApplicationCache.available? + ApplicationCache.new + else + DownloadCache.new(Pathname.new(Dir.tmpdir), JavaBuildpack::Util::Cache::CACHED_RESOURCES_DIRECTORY) + end + end + + end + + end + + end + end +end diff --git a/spec/java_buildpack/util/cache/cache_factory_spec.rb b/spec/java_buildpack/util/cache/cache_factory_spec.rb new file mode 100644 index 0000000000..aa554466d0 --- /dev/null +++ b/spec/java_buildpack/util/cache/cache_factory_spec.rb @@ -0,0 +1,49 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'application_helper' +require 'internet_availability_helper' +require 'logging_helper' +require 'java_buildpack/util/cache/application_cache' +require 'java_buildpack/util/cache/cache_factory' +require 'java_buildpack/util/cache/download_cache' + +describe JavaBuildpack::Util::Cache::CacheFactory do + include_context 'application_helper' + include_context 'internet_availability_helper' + include_context 'logging_helper' + + previous_arg_value = ARGV[1] + + before do + ARGV[1] = nil + end + + after do + ARGV[1] = previous_arg_value + end + + it 'returns an ApplicationCache if ARGV[1] is defined' do + ARGV[1] = app_dir + + expect(described_class.create).to be_instance_of JavaBuildpack::Util::Cache::ApplicationCache + end + + it 'returns a DownloadCache if ARGV[1] is not defined' do + expect(described_class.create).to be_instance_of JavaBuildpack::Util::Cache::DownloadCache + end + +end From 9d3bc1968af27bf96deeb1688a8438d5ba95a2f4 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 16 Aug 2017 09:00:33 -0700 Subject: [PATCH 351/812] Improved Logging This change adds some additional debug logging that is useful for diagnosing Caching issues. --- .rubocop.yml | 2 +- lib/java_buildpack/buildpack.rb | 24 ++++++++++++++++++- lib/java_buildpack/component/droplet.rb | 4 ++++ .../util/cache/download_cache.rb | 12 ++++++---- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 630ac2cca7..236b840043 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -31,7 +31,7 @@ Metrics/CyclomaticComplexity: Metrics/LineLength: Max: 120 Metrics/MethodLength: - Max: 18 + Max: 20 Metrics/ParameterLists: Max: 8 Metrics/PerceivedComplexity: diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index b7183f2ca9..fd7a2796d5 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -25,6 +25,7 @@ require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/component/security_providers' require 'java_buildpack/logging/logger_factory' +require 'java_buildpack/util/cache/application_cache' require 'java_buildpack/util/colorize' require 'java_buildpack/util/configuration_utils' require 'java_buildpack/util/constantize' @@ -66,6 +67,8 @@ def compile component_detection('framework', @frameworks, false).each(&:compile) container.compile + + log_cache_contents end # Generates the payload required to run the application. The payload format is defined by the @@ -111,8 +114,10 @@ def initialize(app_dir, application) @logger = Logging::LoggerFactory.instance.get_logger Buildpack @buildpack_version = BuildpackVersion.new + log_arguments log_environment_variables log_application_contents application + log_cache_contents @java_opts = Component::JavaOpts.new(app_dir) @@ -187,7 +192,24 @@ def log_application_contents(application) paths = [] application.root.find { |f| paths << f.relative_path_from(application.root).to_s } - "Application Contents: #{paths}" + "Application Contents (#{application.root}): #{paths}" + end + end + + def log_arguments + @logger.debug { "Arguments: #{$PROGRAM_NAME} #{ARGV}" } + end + + def log_cache_contents + return unless JavaBuildpack::Util::Cache::ApplicationCache.available? + + cache_root = Pathname.new JavaBuildpack::Util::Cache::ApplicationCache.application_cache_directory + + @logger.debug do + paths = [] + cache_root.find { |f| paths << f.relative_path_from(cache_root).to_s } + + "Cache Contents (#{cache_root}): #{paths}" end end diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index 2cff780b68..4f602a8434 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -99,6 +99,10 @@ def initialize(additional_libraries, component_id, env_vars, extension_directori buildpack_root = root + '.java-buildpack' sandbox_root = buildpack_root + component_id + @logger.debug { "Droplet root: #{root}" } + @logger.debug { "Buildpack root: #{buildpack_root}" } + @logger.debug { "Sandbox root: #{sandbox_root}" } + @sandbox = JavaBuildpack::Util::FilteringPathname.new(sandbox_root, ->(path) { in?(path, sandbox_root) }, true) @root = JavaBuildpack::Util::FilteringPathname.new( diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index f67fd742e4..f81d958993 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -169,7 +169,7 @@ def cache_etag(response, cached_file) return unless etag - @logger.debug { "Persisting etag: #{etag}" } + @logger.debug { "Persisting Etag: #{etag}" } cached_file.etag(File::CREAT | File::WRONLY | File::BINARY) do |f| f.truncate(0) @@ -183,7 +183,7 @@ def cache_last_modified(response, cached_file) return unless last_modified - @logger.debug { "Persisting last-modified: #{last_modified}" } + @logger.debug { "Persisting Last-Modified: #{last_modified}" } cached_file.last_modified(File::CREAT | File::WRONLY | File::BINARY) do |f| f.truncate(0) @@ -293,10 +293,12 @@ def request(uri, cached_file) if cached_file.etag? cached_file.etag(File::RDONLY | File::BINARY) { |f| request['If-None-Match'] = File.read(f) } end + @logger.debug { "Adding If-None-Match: #{request['If-None-Match']}" } if cached_file.last_modified? cached_file.last_modified(File::RDONLY | File::BINARY) { |f| request['If-Modified-Since'] = File.read(f) } end + @logger.debug { "Adding If-Modified-Since: #{request['If-Modified-Since']}" } @logger.debug { "Request: #{request.path}, #{request.to_hash}" } request @@ -307,8 +309,10 @@ def secure?(uri) end def update(uri, cached_file) - proxy(uri).start(uri.host, uri.port, http_options(uri)) do |http| - @logger.debug { "HTTP: #{http.address}, #{http.port}, #{http_options(uri)}" } + http_options = http_options(uri) + + proxy(uri).start(uri.host, uri.port, http_options) do |http| + @logger.debug { "HTTP: #{http.address}, #{http.port}, #{http_options}" } debug_ssl(http) if secure?(uri) attempt_update(cached_file, http, uri) From 84952f9e858b8455ccc9bf143443d0045ca6adf2 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 16 Aug 2017 09:12:42 -0700 Subject: [PATCH 352/812] Polishing This polishes up some log messages, adding color to them. --- lib/java_buildpack/buildpack.rb | 4 ++-- lib/java_buildpack/framework/aspectj_weaver_agent.rb | 2 +- lib/java_buildpack/framework/debug.rb | 6 +++++- lib/java_buildpack/framework/jmx.rb | 2 +- spec/java_buildpack/framework/jrebel_agent_spec.rb | 3 +++ 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index fd7a2796d5..e7083fa7c0 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -203,9 +203,9 @@ def log_arguments def log_cache_contents return unless JavaBuildpack::Util::Cache::ApplicationCache.available? - cache_root = Pathname.new JavaBuildpack::Util::Cache::ApplicationCache.application_cache_directory - @logger.debug do + cache_root = Pathname.new JavaBuildpack::Util::Cache::ApplicationCache.application_cache_directory + paths = [] cache_root.find { |f| paths << f.relative_path_from(cache_root).to_s } diff --git a/lib/java_buildpack/framework/aspectj_weaver_agent.rb b/lib/java_buildpack/framework/aspectj_weaver_agent.rb index 466a4a5b16..ac9a3542e6 100644 --- a/lib/java_buildpack/framework/aspectj_weaver_agent.rb +++ b/lib/java_buildpack/framework/aspectj_weaver_agent.rb @@ -41,7 +41,7 @@ def detect # (see JavaBuildpack::Component::BaseComponent#compile) def compile - puts "-----> AspectJ #{version} Runtime Weaving Enabled" + puts "#{'----->'.red.bold} #{'AspectJ'.blue.bold} #{version.to_s.blue} Runtime Weaving enabled" end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index 21b17e79fa..0ff8605bb5 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -30,7 +30,7 @@ def detect # (see JavaBuildpack::Component::BaseComponent#compile) def compile - puts "-----> Debugging Enabled on port #{port}#{', suspended on start' if @configuration['suspend']}" + puts "#{'----->'.red.bold} #{'Debugging'.blue.bold} enabled on port #{port}#{suspend_message}" end # (see JavaBuildpack::Component::BaseComponent#release) @@ -56,6 +56,10 @@ def suspend @configuration['suspend'] ? 'y' : 'n' end + def suspend_message + ', suspended on start' if @configuration['suspend'] + end + end end diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 65b7ee9f77..50fa5cfb9d 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -30,7 +30,7 @@ def detect # (see JavaBuildpack::Component::BaseComponent#compile) def compile - puts "-----> JMX Enabled on port #{port}" + puts "#{'----->'.red.bold} #{'JMX'.blue.bold} enabled on port #{port}" end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb index de55c96917..8ba330ba36 100644 --- a/spec/java_buildpack/framework/jrebel_agent_spec.rb +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -26,16 +26,19 @@ it 'detects when rebel-remote.xml is present in the top-level directory', app_fixture: 'framework_jrebel_app_simple' do + expect(component.detect).to eq("jrebel-agent=#{version}") end it 'detects when rebel-remote.xml is present in WEB-INF/classes', app_fixture: 'framework_jrebel_app_war' do + expect(component.detect).to eq("jrebel-agent=#{version}") end it 'detects when rebel-remote.xml is present inside an embedded JAR', app_fixture: 'framework_jrebel_app_war_with_jar' do + expect(component.detect).to eq("jrebel-agent=#{version}") end From dccdadb5504250f003b66dc4cd3dac1428e47bcf Mon Sep 17 00:00:00 2001 From: Donnie Propst Date: Wed, 16 Aug 2017 14:04:13 -0400 Subject: [PATCH 353/812] Update Contrast Framework for Next Release This change makes a change to the Contrast Framework to prepare for naming changes coming in a forthcoming release. [#480] --- .../framework/contrast_security_agent.rb | 18 ++++++++++----- .../framework/contrast_security_agent_spec.rb | 22 ++++++++++++++++++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index 812490fbcc..d6e252d3f4 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -39,9 +39,9 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts - .add_system_property('contrast.dir', '$TMPDIR') - .add_system_property('contrast.override.appname', application_name) - .add_preformatted_options("-javaagent:#{qualify_path(@droplet.sandbox + jar_name, @droplet.root)}=" \ + .add_system_property('contrast.dir', '$TMPDIR') + .add_system_property('contrast.override.appname', application_name) + .add_preformatted_options("-javaagent:#{qualify_path(@droplet.sandbox + jar_name, @droplet.root)}=" \ "#{qualify_path(contrast_config, @droplet.root)}") end @@ -49,7 +49,11 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#jar_name) def jar_name - "contrast-engine-#{@version.to_s.split('_')[0]}.jar" + if @version < JAVA_AGENT_VERSION + "contrast-engine-#{@version[0]}.#{@version[1]}.#{@version[2]}.jar" + else + "java-agent-#{@version[0]}.#{@version[1]}.#{@version[2]}.jar" + end end # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) @@ -63,7 +67,9 @@ def supports? CONTRAST_FILTER = 'contrast-security'.freeze - PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins.'.freeze + JAVA_AGENT_VERSION = JavaBuildpack::Util::TokenizedVersion.new('3.4.3').freeze + + PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins'.freeze SERVICE_KEY = 'service_key'.freeze @@ -71,7 +77,7 @@ def supports? USERNAME = 'username'.freeze - private_constant :API_KEY, :CONTRAST_FILTER, :PLUGIN_PACKAGE, :SERVICE_KEY, :TEAMSERVER_URL, :USERNAME + private_constant :API_KEY, :CONTRAST_FILTER, :PLUGIN_PACKAGE, :SERVICE_KEY, :TEAMSERVER_URL, :USERNAME, :JAVA_AGENT_VERSION def add_contrast(doc, credentials) contrast = doc.add_element('contrast') diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb index 3319b1f2bb..8ea1ec57c4 100644 --- a/spec/java_buildpack/framework/contrast_security_agent_spec.rb +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -33,7 +33,6 @@ allow(services).to receive(:one_service?).with(/contrast-security/, 'api_key', 'service_key', 'teamserver_url', 'username').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'teamserver_url' => 'a_url', - 'org_uuid' => '12345', 'username' => 'contrast_user', 'api_key' => 'api_test', 'service_key' => 'service_test' }) @@ -50,6 +49,27 @@ expect(sandbox + 'contrast-engine-0.0.0.jar').to exist end + it 'uses contrast-engine for versions < 3.4.3' do + + tokenized_version = JavaBuildpack::Util::TokenizedVersion.new('3.4.2_756') + allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item) do |&block| + block.call(tokenized_version) if block + end.and_return([tokenized_version, uri]) + + component.release + expect(java_opts.to_s).to include('contrast-engine-3.4.2.jar') + end + + it 'uses java-agent for versions >= 3.4.3' do + tokenized_version = JavaBuildpack::Util::TokenizedVersion.new('3.4.3_000') + allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item) do |&block| + block.call(tokenized_version) if block + end.and_return([tokenized_version, uri]) + + component.release + expect(java_opts.to_s).to include('java-agent-3.4.3.jar') + end + it 'updates JAVA_OPTS' do component.release From c70117667d44a7db3b4b99f1910c1857b6b582e3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 16 Aug 2017 14:01:43 -0700 Subject: [PATCH 354/812] Polishing This change does some cosmetic polishing for the previous contribution to match house style. [resolves #480] --- .../framework/contrast_security_agent.rb | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index d6e252d3f4..7c9b224c68 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -39,9 +39,9 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts - .add_system_property('contrast.dir', '$TMPDIR') - .add_system_property('contrast.override.appname', application_name) - .add_preformatted_options("-javaagent:#{qualify_path(@droplet.sandbox + jar_name, @droplet.root)}=" \ + .add_system_property('contrast.dir', '$TMPDIR') + .add_system_property('contrast.override.appname', application_name) + .add_preformatted_options("-javaagent:#{qualify_path(@droplet.sandbox + jar_name, @droplet.root)}=" \ "#{qualify_path(contrast_config, @droplet.root)}") end @@ -49,11 +49,7 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#jar_name) def jar_name - if @version < JAVA_AGENT_VERSION - "contrast-engine-#{@version[0]}.#{@version[1]}.#{@version[2]}.jar" - else - "java-agent-#{@version[0]}.#{@version[1]}.#{@version[2]}.jar" - end + @version < INFLECTION_VERSION ? "contrast-engine-#{short_version}.jar" : "java-agent-#{short_version}.jar" end # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) @@ -67,7 +63,7 @@ def supports? CONTRAST_FILTER = 'contrast-security'.freeze - JAVA_AGENT_VERSION = JavaBuildpack::Util::TokenizedVersion.new('3.4.3').freeze + INFLECTION_VERSION = JavaBuildpack::Util::TokenizedVersion.new('3.4.3').freeze PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins'.freeze @@ -77,7 +73,8 @@ def supports? USERNAME = 'username'.freeze - private_constant :API_KEY, :CONTRAST_FILTER, :PLUGIN_PACKAGE, :SERVICE_KEY, :TEAMSERVER_URL, :USERNAME, :JAVA_AGENT_VERSION + private_constant :API_KEY, :CONTRAST_FILTER, :INFLECTION_VERSION, :PLUGIN_PACKAGE, :SERVICE_KEY, :TEAMSERVER_URL, + :USERNAME def add_contrast(doc, credentials) contrast = doc.add_element('contrast') @@ -115,6 +112,10 @@ def contrast_config @droplet.sandbox + 'contrast.config' end + def short_version + "#{@version[0]}.#{@version[1]}.#{@version[2]}" + end + def write_configuration(credentials) doc = REXML::Document.new From 635a4ebfb6a6e24af255e84ce4c6173ba694da04 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 16 Aug 2017 12:48:51 -0700 Subject: [PATCH 355/812] Multi Buildpack Support This change adds a new framework for multi buildpack support. This framework honors the core multi buildpack contract of including bin/ in $PATH and lib/ in $LD_LIBRARY_PATH as well as defining 11 additional keys that non-final buildpacks can use to contributed to the Java Buildpack. --- README.md | 1 + bin/finalize | 25 ++ config/components.yml | 6 +- docs/framework-multi_buildpack.md | 40 +++ .../framework/multi_buildpack.rb | 308 ++++++++++++++++++ .../0/bin/.gitkeep | 0 .../0/config.yml | 3 + .../0/lib/.gitkeep | 0 .../framework_multi_buildpack_deps/1/.gitkeep | 0 .../2/config.yml | 41 +++ .../framework/multi_buildpack_spec.rb | 276 ++++++++++++++++ 11 files changed, 698 insertions(+), 2 deletions(-) create mode 100755 bin/finalize create mode 100644 docs/framework-multi_buildpack.md create mode 100644 lib/java_buildpack/framework/multi_buildpack.rb create mode 100644 spec/fixtures/framework_multi_buildpack_deps/0/bin/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/0/config.yml create mode 100644 spec/fixtures/framework_multi_buildpack_deps/0/lib/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/1/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/2/config.yml create mode 100644 spec/java_buildpack/framework/multi_buildpack_spec.rb diff --git a/README.md b/README.md index a653d75365..d44868ddbb 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi * [JMX](docs/framework-jmx.md) ([Configuration](docs/framework-jmx.md#configuration)) * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) * [MariaDB JDBC](docs/framework-maria_db_jdbc.md) ([Configuration](docs/framework-maria_db_jdbc.md#configuration)) (also supports MySQL) + * [Multiple Buildpack](docs/framework-multi_buildpack.md) * [Metric Writer](docs/framework-metric_writer.md) ([Configuration](docs/framework-metric_writer.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) diff --git a/bin/finalize b/bin/finalize new file mode 100755 index 0000000000..2b7c8300a3 --- /dev/null +++ b/bin/finalize @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +$stdout.sync = true +$stderr.sync = true +$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) + +require 'java_buildpack/buildpack' + +app_dir = ARGV[0] + +JavaBuildpack::Buildpack.with_buildpack(app_dir, 'Finalize failed with exception %s', &:compile) diff --git a/config/components.yml b/config/components.yml index 4c96331332..ec8c8ff1f0 100644 --- a/config/components.yml +++ b/config/components.yml @@ -34,9 +34,11 @@ jres: # - "JavaBuildpack::Jre::OracleJRE" # - "JavaBuildpack::Jre::ZuluJRE" -# Frameworks are processed in order. Any Java Opts added by the JavaOpts framework will be specified in the start -# command after any Java Opts added by previous frameworks. +# Frameworks are processed in order. +# The MultiBuildpack framework is first in order to allow any framework to override contributions from earlier buildpacks +# The JavaOpts is last in order to allow any user-defined JAVA_OPTS to override contributions from earlier frameworks frameworks: + - "JavaBuildpack::Framework::MultiBuildpack" - "JavaBuildpack::Framework::AppDynamicsAgent" - "JavaBuildpack::Framework::AspectjWeaverAgent" - "JavaBuildpack::Framework::ClientCertificateMapper" diff --git a/docs/framework-multi_buildpack.md b/docs/framework-multi_buildpack.md new file mode 100644 index 0000000000..29f165c9d0 --- /dev/null +++ b/docs/framework-multi_buildpack.md @@ -0,0 +1,40 @@ +# Multiple Buildpack Framework +The Multiple Buildpack Framework enables the Java Buildpack to act as the final buildpack in a multiple buildpack deployment. It reads the contributions of other, earlier buildpacks and incorporates them into its standard staging. + +The Java Options Framework contributes arbitrary Java options to the application at runtime. + + + + + + + + + + +
Detection CriterionExistence of buildpack contribution directories (typically /tmp/<RANDOM>/deps/<INDEX> containing a config.yml file.
Tagsmulti-buildpack=<BUILDPACK_NAME>,...
+Tags are printed to standard output by the buildpack detect script + +## Multiple Buildpack Integration API +When the Java Buildpack acts as the final buildpack in a multiple buildpack deployment it honors the following core contract integration points. + +| Integration Point | Buildpack Usage +| ----------------- | --------------- +| `/bin` | An existing `/bin` directory contributed by a non-final buildpack will be added to the `$PATH` of the application as it executes +| `/lib` | An existing `/lib` directory contributed by a non-final buildpack will be added to the `$LD_LIBRARY_PATH` of the application as it executes + +In addition to the core contract, the Java Buildpack defines the following keys in `config.yml` as extension points for contributing to the application. **All keys are optional, and all paths are absolute.** + +| Key | Type | Description +| --- | ---- | ----------- +| `additional_libraries` | `[ path ]` | An array of absolute paths to libraries will be added to the application's classpath +| `environment_variables` | `{ string, ( path \| string ) }` | A hash of string keys to absolute path or string values that will be added as environment variables +| `extension_directories` | `[ path ]` | An array of absolute paths to directories containing JRE extensions +| `java_opts.agentpaths` | `[ path ]` | An array of absolute paths to libraries that will be added as agents +| `java_opts.agentpaths_with_props` | `{ path, { string, string } }` | A nested hash with absolute paths keys and hashes of string keys and string values as a value that will be added as agents with properties +| `java_opts.bootclasspath_ps` | `[ path ]` | An array of absolute paths that will be added to the application's bootclasspath +| `java_opts.javaagents` | `[ path ]` | An array of absolute paths that will be added as javaagents +| `java_opts.preformatted_options` | `[ string ]` | An array of strings that will be added as options without modification +| `java_opts.options` | `{ string, ( path \| string ) }` | A hash of string keys to absolute path or string values that will be added as options +| `java_opts.system_properties` | `{ string , ( path \| string ) }` | A hash of string keys to absolute path or string values that will be added as system properties +| `security_providers` | `[ string ]` | An array of strings to be added to list of security providers diff --git a/lib/java_buildpack/framework/multi_buildpack.rb b/lib/java_buildpack/framework/multi_buildpack.rb new file mode 100644 index 0000000000..5a83a8cd00 --- /dev/null +++ b/lib/java_buildpack/framework/multi_buildpack.rb @@ -0,0 +1,308 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'pathname' +require 'java_buildpack/component/base_component' +require 'java_buildpack/framework' +require 'java_buildpack/logging/logger_factory' +require 'java_buildpack/util/qualify_path' +require 'yaml' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for multi buildpack support. + class MultiBuildpack < JavaBuildpack::Component::BaseComponent + include JavaBuildpack::Util + + # (see JavaBuildpack::Component::BaseComponent#initialize) + def initialize(context) + super(context) + + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger MultiBuildpack + @logger.debug { "Dependencies Directory: #{ARGV[3]}" } + end + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + !dep_directories.empty? ? "multi-buildpack=#{names(dep_directories).join(',')}" : nil + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + puts "#{'----->'.red.bold} #{'Multiple Buildpacks'.blue.bold} detected" + + dep_directories.each do |dep_directory| + config = config(config_file(dep_directory)) + name = name(config) + + log_configuration config + log_dep_contents dep_directory + + contributions = [ + add_bin(dep_directory), + add_lib(dep_directory), + add_additional_libraries(config), + add_environment_variables(config), + add_extension_directories(config), + add_java_opts(config), + add_security_providers(config) + ] + + puts " #{name}#{contributions_message(contributions)}" + end + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + dep_directories.each do |dep_directory| + config = config(config_file(dep_directory)) + + add_bin(dep_directory) + add_lib(dep_directory) + add_additional_libraries(config) + add_environment_variables(config) + add_extension_directories(config) + add_java_opts(config) + add_security_providers(config) + end + end + + private + + def add_additional_libraries(config) + additional_libraries = config['config']['additional_libraries'] + return unless additional_libraries + + additional_libraries.each do |additional_library| + @droplet.additional_libraries << Pathname.new(additional_library) + end + + 'Additional Libraries' + end + + def add_agentpaths(java_opts) + agentpaths = java_opts['agentpaths'] + return unless agentpaths + + agentpaths.each do |agentpath| + @droplet.java_opts.add_agentpath Pathname.new(agentpath) + end + + 'Agents' + end + + def add_agentpaths_with_props(java_opts) + agentpaths = java_opts['agentpaths_with_props'] + return unless agentpaths + + agentpaths.each do |agentpath, props| + @droplet.java_opts.add_agentpath_with_props Pathname.new(agentpath), props + end + + 'Agent with Properties' + end + + def add_bin(dep_directory) + bin_directory = dep_directory + 'bin' + return unless bin_directory.exist? + + @droplet.environment_variables + .add_environment_variable('PATH', "$PATH:#{qualify_path(bin_directory, @droplet.root)}") + + '$PATH' + end + + def add_bootclasspath_ps(java_opts) + bootclasspath_ps = java_opts['bootclasspath_ps'] + return unless bootclasspath_ps + + bootclasspath_ps.each do |bootclasspath_p| + @droplet.java_opts.add_bootclasspath_p Pathname.new(bootclasspath_p) + end + + 'Boot Classpaths' + end + + def add_environment_variables(config) + environment_variables = config['config']['environment_variables'] + return unless environment_variables + + environment_variables.each do |key, value| + path = Pathname.new(value) + + if path.exist? + @droplet.environment_variables.add_environment_variable key, path + else + @droplet.environment_variables.add_environment_variable key, value + end + end + + 'Environment Variables' + end + + def add_extension_directories(config) + extension_directories = config['config']['extension_directories'] + return unless extension_directories + + extension_directories.each do |extension_directory| + @droplet.extension_directories << Pathname.new(extension_directory) + end + + 'Extension Directories' + end + + def add_javaagent(java_opts) + javaagents = java_opts['javaagents'] + return unless javaagents + + javaagents.each do |javaagent| + @droplet.java_opts.add_javaagent Pathname.new(javaagent) + end + + 'Java Agents' + end + + def add_java_opts(config) + java_opts = config['config']['java_opts'] + return unless java_opts + + [ + add_agentpaths(java_opts), + add_agentpaths_with_props(java_opts), + add_bootclasspath_ps(java_opts), + add_javaagent(java_opts), + add_options(java_opts), + add_preformatted_options(java_opts), + add_system_properties(java_opts) + ] + end + + def add_lib(dep_directory) + lib_directory = dep_directory + 'lib' + return unless lib_directory.exist? + + @droplet.environment_variables + .add_environment_variable('LD_LIBRARY_PATH', + "$LD_LIBRARY_PATH:#{qualify_path(lib_directory, @droplet.root)}") + + '$LD_LIBRARY_PATH' + end + + def add_options(java_opts) + options = java_opts['options'] + return unless options + + options.each do |key, value| + path = Pathname.new(value) + + if path.exist? + @droplet.java_opts.add_option key, path + else + @droplet.java_opts.add_option key, value + end + end + + 'Options' + end + + def add_preformatted_options(java_opts) + preformatted_options = java_opts['preformatted_options'] + return unless preformatted_options + + preformatted_options.each do |preformatted_option| + @droplet.java_opts.add_preformatted_options preformatted_option + end + + 'Preformatted Options' + end + + def add_security_providers(config) + security_providers = config['config']['security_providers'] + return unless security_providers + + security_providers.each do |security_provider| + @droplet.security_providers << security_provider + end + + 'Security Providers' + end + + def add_system_properties(java_opts) + system_properties = java_opts['system_properties'] + return unless system_properties + + system_properties.each do |key, value| + path = Pathname.new(value) + + if path.exist? + @droplet.java_opts.add_system_property key, path + else + @droplet.java_opts.add_system_property key, value + end + end + + 'System Properties' + end + + def config(config_file) + YAML.load_file(config_file) + end + + def config_file(dep_directory) + dep_directory + 'config.yml' + end + + def contributions_message(contributions) + return if contributions.compact.empty? + " contributed to: #{contributions.flatten.compact.sort.join(', ')}" + end + + def dep_directories + deps = Pathname.glob('/tmp/*/deps').first + return [] unless deps + + deps + .children + .select { |dep_directory| config_file(dep_directory).exist? } + .sort_by(&:basename) + end + + def log_configuration(config) + @logger.debug { "Configuration: #{config}" } + end + + def log_dep_contents(dep_directory) + @logger.debug do + paths = [] + dep_directory.find { |f| paths << f.relative_path_from(dep_directory).to_s } + + "Application Contents (#{dep_directory}): #{paths}" + end + end + + def name(config) + config['name'] + end + + def names(dep_directories) + dep_directories.map { |dep_directory| name(config(config_file(dep_directory))) } + end + + end + + end +end diff --git a/spec/fixtures/framework_multi_buildpack_deps/0/bin/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/0/bin/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/0/config.yml b/spec/fixtures/framework_multi_buildpack_deps/0/config.yml new file mode 100644 index 0000000000..c15a4aaac4 --- /dev/null +++ b/spec/fixtures/framework_multi_buildpack_deps/0/config.yml @@ -0,0 +1,3 @@ +--- +name: test-buildpack-0 +config: {} diff --git a/spec/fixtures/framework_multi_buildpack_deps/0/lib/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/0/lib/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/1/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/1/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/2/config.yml b/spec/fixtures/framework_multi_buildpack_deps/2/config.yml new file mode 100644 index 0000000000..804c4a42a3 --- /dev/null +++ b/spec/fixtures/framework_multi_buildpack_deps/2/config.yml @@ -0,0 +1,41 @@ +--- +name: test-buildpack-2 +config: + additional_libraries: + - /multi-test-additional-library-1 + - /multi-test-additional-library-2 + environment_variables: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + extension_directories: + - /multi-test-extension-directory-1 + - /multi-test-extension-directory-2 + java_opts: + agentpaths: + - /multi-test-agent-1 + - /multi-test-agent-2 + agentpaths_with_props: + /multi-test-agent-1: + test-key-1: test-value-1 + test-key-2: test-value-2 + /multi-test-agent-2: + test-key-1: test-value-1 + test-key-2: test-value-2 + bootclasspath_ps: + - /multi-test-bootclasspath-p-1 + - /multi-test-bootclasspath-p-2 + javaagents: + - /multi-test-java-agent-1 + - /multi-test-java-agent-2 + preformatted_options: + - multi-test-preformatted-option-1 + - multi-test-preformatted-option-2 + options: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + system_properties: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + security_providers: + - multi-test-security-provider-1 + - multi-test-security-provider-2 diff --git a/spec/java_buildpack/framework/multi_buildpack_spec.rb b/spec/java_buildpack/framework/multi_buildpack_spec.rb new file mode 100644 index 0000000000..2094e221e3 --- /dev/null +++ b/spec/java_buildpack/framework/multi_buildpack_spec.rb @@ -0,0 +1,276 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'pathname' +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/multi_buildpack' + +describe JavaBuildpack::Framework::MultiBuildpack do + include_context 'component_helper' + + before do + allow(Pathname).to receive(:glob).with('/tmp/*/deps').and_return([Pathname.new(app_dir)]) + end + + it 'does not detect without deps' do + expect(component.detect).to be_nil + end + + it 'detects when deps with config.yml exist', + app_fixture: 'framework_multi_buildpack_deps' do + + expect(component.detect).to eq('multi-buildpack=test-buildpack-0,test-buildpack-2') + end + + it 'adds bin/ directory to $PATH during compile if it exists', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(environment_variables).to include('PATH=$PATH:$PWD/0/bin') + end + + it 'adds bin/ directory to $PATH during release if it exists', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(environment_variables).to include('PATH=$PATH:$PWD/0/bin') + end + + it 'adds lib/ directory to $LD_LIBRARY_PATH during compile if it exists', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(environment_variables).to include('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/0/lib') + end + + it 'adds lib/ directory to $LD_LIBRARY_PATH during release if it exists', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(environment_variables).to include('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/0/lib') + end + + it 'adds additional_libraries during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(additional_libraries).to include(Pathname.new('/multi-test-additional-library-1')) + expect(additional_libraries).to include(Pathname.new('/multi-test-additional-library-2')) + end + + it 'adds additional_libraries during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(additional_libraries).to include(Pathname.new('/multi-test-additional-library-1')) + expect(additional_libraries).to include(Pathname.new('/multi-test-additional-library-2')) + end + + it 'adds agentpaths during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-1')}") + expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-2')}") + end + + it 'adds agentpaths during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-1')}") + expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-2')}") + end + + it 'adds agentpaths_with_props during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-1')}=" \ + 'test-key-1=test-value-1,test-key-2=test-value-2') + expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-2')}=" \ + 'test-key-1=test-value-1,test-key-2=test-value-2') + end + + it 'adds agentpaths_with_props during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-1')}=" \ + 'test-key-1=test-value-1,test-key-2=test-value-2') + expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-2')}=" \ + 'test-key-1=test-value-1,test-key-2=test-value-2') + end + + it 'adds bootclasspath_ps during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(java_opts).to include("-Xbootclasspath/p:$PWD/#{qualify_path('/multi-test-bootclasspath-p-1')}") + expect(java_opts).to include("-Xbootclasspath/p:$PWD/#{qualify_path('/multi-test-bootclasspath-p-2')}") + end + + it 'adds bootclasspath_ps during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(java_opts).to include("-Xbootclasspath/p:$PWD/#{qualify_path('/multi-test-bootclasspath-p-1')}") + expect(java_opts).to include("-Xbootclasspath/p:$PWD/#{qualify_path('/multi-test-bootclasspath-p-2')}") + end + + it 'adds environment_variables during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(environment_variables).to include('multi-test-key-1=multi-test-value-1') + expect(environment_variables).to include('multi-test-key-2=multi-test-value-2') + end + + it 'adds environment_variables during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(environment_variables).to include('multi-test-key-1=multi-test-value-1') + expect(environment_variables).to include('multi-test-key-2=multi-test-value-2') + end + + it 'adds extension_directories during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(extension_directories).to include(Pathname.new('/multi-test-extension-directory-1')) + expect(extension_directories).to include(Pathname.new('/multi-test-extension-directory-2')) + end + + it 'adds extension_directories during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(extension_directories).to include(Pathname.new('/multi-test-extension-directory-1')) + expect(extension_directories).to include(Pathname.new('/multi-test-extension-directory-2')) + end + + it 'adds javaagents during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(java_opts).to include("-javaagent:$PWD/#{qualify_path('/multi-test-java-agent-1')}") + expect(java_opts).to include("-javaagent:$PWD/#{qualify_path('/multi-test-java-agent-2')}") + end + + it 'adds javaagents during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(java_opts).to include("-javaagent:$PWD/#{qualify_path('/multi-test-java-agent-1')}") + expect(java_opts).to include("-javaagent:$PWD/#{qualify_path('/multi-test-java-agent-2')}") + end + + it 'adds options during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(java_opts).to include('multi-test-key-1=multi-test-value-1') + expect(java_opts).to include('multi-test-key-2=multi-test-value-2') + end + + it 'adds options during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(java_opts).to include('multi-test-key-1=multi-test-value-1') + expect(java_opts).to include('multi-test-key-2=multi-test-value-2') + end + + it 'adds preformatted_options during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(java_opts).to include('multi-test-preformatted-option-1') + expect(java_opts).to include('multi-test-preformatted-option-2') + end + + it 'adds preformatted_options during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(java_opts).to include('multi-test-preformatted-option-1') + expect(java_opts).to include('multi-test-preformatted-option-2') + end + + it 'adds security_providers during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(security_providers).to include('multi-test-security-provider-1') + expect(security_providers).to include('multi-test-security-provider-2') + end + + it 'adds security_providers during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(security_providers).to include('multi-test-security-provider-1') + expect(security_providers).to include('multi-test-security-provider-2') + end + + it 'adds system_properties during compile', + app_fixture: 'framework_multi_buildpack_deps' do + + component.compile + + expect(java_opts).to include('-Dmulti-test-key-1=multi-test-value-1') + expect(java_opts).to include('-Dmulti-test-key-2=multi-test-value-2') + end + + it 'adds system_properties during release', + app_fixture: 'framework_multi_buildpack_deps' do + + component.release + + expect(java_opts).to include('-Dmulti-test-key-1=multi-test-value-1') + expect(java_opts).to include('-Dmulti-test-key-2=multi-test-value-2') + end + + def qualify_path(path) + Pathname.new(path).relative_path_from(application.root) + end + +end From b264792494ceaedbd90ceafc9b58b67bf300814e Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 21 Aug 2017 08:54:40 -0700 Subject: [PATCH 356/812] Cached Filename of Constant Length Previously, the name of a cached file was a sanitized version of the URI. Recently, a user starting caching a file that had a URI that was longer than 255 characters, causing issues with writing a filename of that length to the filesystem. The solution to this was to hash the URI (SHA256 in this case) in order to get a shorter and constant-length filename. [resolves #484] --- lib/java_buildpack/util/cache/cached_file.rb | 5 ++++- spec/java_buildpack/util/cache/cached_file_spec.rb | 3 ++- spec/java_buildpack/util/cache/download_cache_spec.rb | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/util/cache/cached_file.rb b/lib/java_buildpack/util/cache/cached_file.rb index 966ed23b0d..747a2995c6 100644 --- a/lib/java_buildpack/util/cache/cached_file.rb +++ b/lib/java_buildpack/util/cache/cached_file.rb @@ -13,8 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +require 'digest' require 'fileutils' require 'java_buildpack/util/cache' +require 'java_buildpack/util/sanitizer' module JavaBuildpack module Util @@ -24,6 +26,7 @@ module Cache # # Note: this class is thread-safe, however access to the cached files is not class CachedFile + include JavaBuildpack::Util # Creates an instance of the cached file. Files created and expected by this class will all be rooted at # +cache_root+. @@ -32,7 +35,7 @@ class CachedFile # @param [String] uri a uri which uniquely identifies the file in the cache # @param [Boolean] mutable whether the cached file should be mutable def initialize(cache_root, uri, mutable) - key = URI.escape(uri.sanitize_uri, ':/&') + key = Digest::SHA256.hexdigest uri.sanitize_uri @cached = cache_root + "#{key}.cached" @etag = cache_root + "#{key}.etag" @last_modified = cache_root + "#{key}.last_modified" diff --git a/spec/java_buildpack/util/cache/cached_file_spec.rb b/spec/java_buildpack/util/cache/cached_file_spec.rb index e2dfd25f5e..097d7975e0 100644 --- a/spec/java_buildpack/util/cache/cached_file_spec.rb +++ b/spec/java_buildpack/util/cache/cached_file_spec.rb @@ -15,6 +15,7 @@ require 'spec_helper' require 'application_helper' +require 'digest' require 'fileutils' require 'java_buildpack/util/cache/cached_file' @@ -104,7 +105,7 @@ end def cache_file(extension) - app_dir + "http%3A%2F%2Ffoo-uri%2F.#{extension}" + app_dir + "#{Digest::SHA256.hexdigest('http://foo-uri/')}.#{extension}" end def touch(extension, content = '') diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index b076e7021f..8ac03eae3e 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -17,6 +17,7 @@ require 'application_helper' require 'internet_availability_helper' require 'logging_helper' +require 'digest' require 'fileutils' require 'java_buildpack/util/cache/download_cache' require 'net/http' @@ -337,7 +338,7 @@ end def cache_file(root, extension) - root + "http%3A%2F%2Ffoo-uri%2F.#{extension}" + root + "#{Digest::SHA256.hexdigest('http://foo-uri/')}.#{extension}" end def expect_complete_cache(root) From 89d79cff5f284a041ab820e2ebe00cbca7b3d537 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 15 Sep 2017 07:02:50 -0700 Subject: [PATCH 357/812] Upgrade Ruby This change updates the versions of Ruby in the Docker image that are available for testing. --- ci/docker-image/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 091cec3399..2acd25e0fb 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -30,10 +30,10 @@ RUN eval "$(rbenv init -)" \ && echo 'bundler' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ - && rbenv install 2.2.7 + && rbenv install 2.2.8 RUN eval "$(rbenv init -)" \ - && rbenv install 2.3.4 + && rbenv install 2.3.5 RUN eval "$(rbenv init -)" \ - && rbenv install 2.4.1 + && rbenv install 2.4.2 From ee67663f95cc4faac304df6150f955cce0d00cff Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 15 Sep 2017 07:34:10 -0700 Subject: [PATCH 358/812] Ruby Updates --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 5bc1cc43d4..23a63f524e 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.2.7 +2.2.8 From ab3defebda6b3598707db77f623dbb2678dae1ae Mon Sep 17 00:00:00 2001 From: stipx Date: Tue, 12 Sep 2017 09:58:35 +0200 Subject: [PATCH 359/812] Update Service Detection for Dynatrace Integration This change updates the Dynatrace integration to be more modern and be stricter about credential payloads. It also removes a deprecated integration option and updates documentation to be accurate with the current implementation. [#487] --- docs/framework-dynatrace_one_agent.md | 7 +- .../framework/dynatrace_one_agent.rb | 95 ++++++++----------- .../dynatrace_one_agent/manifest.json | 10 ++ .../framework/dynatrace_one_agent_spec.rb | 67 +++++-------- 4 files changed, 76 insertions(+), 103 deletions(-) diff --git a/docs/framework-dynatrace_one_agent.md b/docs/framework-dynatrace_one_agent.md index b7ddace96e..a50456fcc2 100644 --- a/docs/framework-dynatrace_one_agent.md +++ b/docs/framework-dynatrace_one_agent.md @@ -7,7 +7,7 @@ The Dynatrace SaaS/Managed OneAgent Framework causes an application to be automa Detection CriterionExistence of a single bound Dynatrace SaaS/Managed service.
    -
  • Existence of a Dynatrace SaaS/Managed service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has dynatrace as a substring.
  • +
  • Existence of a Dynatrace SaaS/Managed service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has dynatrace as a substring with at least `environmentid` and `apitoken` set as credentials.
@@ -25,10 +25,9 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- -| `environmentid` | Your Dynatrace environment ID is the unique identifier of your Dynatrace environment. You can find it in the deploy Dynatrace section within your environment. The `environmentid` replaces deprecated ~~`tenant`~~ option. -| `apitoken` | The token for integrating your Dynatrace environment with Cloud Foundry. You can find it in the deploy Dynatrace section within your environment. The `apitoken` replaces deprecated ~~`tenanttoken`~~ option. +| `environmentid` | Your Dynatrace environment ID is the unique identifier of your Dynatrace environment. You can find it in the deploy Dynatrace section within your environment. +| `apitoken` | The token for integrating your Dynatrace environment with Cloud Foundry. You can find it in the deploy Dynatrace section within your environment. | `apiurl` | (Optional) The base URL of the Dynatrace API. If you are using Dynatrace Managed you will need to set this property to `https:///e//api`. If you are using Dynatrace SaaS you don't need to set this property. -| `endpoint` | (Deprecated) The Dynatrace connection endpoint the agent connects to. Please use `apiurl` in combination with `apitoken` for Dynatrace Managed. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 0f19f131b1..00cdc02558 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -30,7 +30,7 @@ class DynatraceOneAgent < JavaBuildpack::Component::VersionedDependencyComponent # @param [Hash] context a collection of utilities used the component def initialize(context) super(context) - @version, @uri = agent_download_url if supports? && supports_apitoken? + @version, @uri = agent_download_url if supports? end # (see JavaBuildpack::Component::BaseComponent#compile) @@ -46,48 +46,43 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = service['credentials'] - @droplet.java_opts.add_agentpath_with_props(agent_path, - SERVER => server(credentials), - TENANT => tenant(credentials), - TENANTTOKEN => tenanttoken(credentials)) + @droplet.java_opts.add_agentpath(agent_path) environment = @application.environment environment_variables = @droplet.environment_variables - unless environment.key?(RUXIT_APPLICATION_ID) - environment_variables.add_environment_variable(RUXIT_APPLICATION_ID, application_id) + unless environment.key?(DT_APPLICATION_ID) + environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) end - environment_variables.add_environment_variable(RUXIT_HOST_ID, host_id) unless environment.key?(RUXIT_HOST_ID) + environment_variables.add_environment_variable(DT_HOST_ID, host_id) unless environment.key?(DT_HOST_ID) + environment_variables.add_environment_variable(DT_TENANT, credentials[ENVIRONMENTID]) + environment_variables.add_environment_variable(DT_TENANTTOKEN, tenanttoken) + environment_variables.add_environment_variable(DT_CONNECTION_POINT, endpoints) end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, [ENVIRONMENTID, TENANT], [APITOKEN, TENANTTOKEN] - end - - def supports_apitoken? - credentials = @application.services.find_service(FILTER)['credentials'] - credentials[APITOKEN] ? true : false + !service.nil? end private - FILTER = /ruxit|dynatrace/ + FILTER = /dynatrace/ - RUXIT_APPLICATION_ID = 'RUXIT_APPLICATIONID'.freeze + DT_APPLICATION_ID = 'DT_APPLICATIONID'.freeze - RUXIT_HOST_ID = 'RUXIT_HOST_ID'.freeze + DT_HOST_ID = 'DT_HOST_ID'.freeze - SERVER = 'server'.freeze + DT_TENANT = 'DT_TENANT'.freeze - TENANT = 'tenant'.freeze + DT_TENANTTOKEN = 'DT_TENANTTOKEN'.freeze - TENANTTOKEN = 'tenanttoken'.freeze + DT_CONNECTION_POINT = 'DT_CONNECTION_POINT'.freeze APITOKEN = 'apitoken'.freeze @@ -95,34 +90,40 @@ def supports_apitoken? ENVIRONMENTID = 'environmentid'.freeze - ENDPOINT = 'endpoint'.freeze - - private_constant :FILTER, :RUXIT_APPLICATION_ID, :RUXIT_HOST_ID, :SERVER, :TENANT, :TENANTTOKEN, :APITOKEN - private_constant :ENVIRONMENTID, :ENDPOINT, :APIURL + private_constant :FILTER, :DT_APPLICATION_ID, :DT_HOST_ID + private_constant :DT_TENANT, :DT_TENANTTOKEN, :DT_CONNECTION_POINT + private_constant :ENVIRONMENTID, :APITOKEN + + def service + candidates = @application.services.select do |candidate| + ( + candidate['name'] =~ FILTER || + candidate['label'] =~ FILTER || + candidate['tags'].any? { |tag| tag =~ FILTER } + ) && + candidate['credentials'][ENVIRONMENTID] && candidate['credentials'][APITOKEN] + end - def agent_dir - @droplet.sandbox + 'agent' + candidates.one? ? candidates.first : nil end def agent_path - libpath = agent_dir + 'lib64/liboneagentloader.so' - libpath = agent_dir + 'lib64/libruxitagentloader.so' unless File.file?(libpath) - libpath + technologies = JSON.parse(File.read(@droplet.sandbox + 'manifest.json'))['technologies'] + java_binaries = technologies['java']['linux-x86-64'] + loader = java_binaries.find { |bin| bin['binarytype'] == 'loader' } + @droplet.sandbox + loader['path'] end def agent_download_url - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = service['credentials'] download_uri = "#{api_base_url}/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&" download_uri += "Api-Token=#{credentials[APITOKEN]}" ['latest', download_uri] end def api_base_url - credentials = @application.services.find_service(FILTER)['credentials'] - return credentials[APIURL] unless credentials[APIURL].nil? - base_url = credentials[ENDPOINT] || credentials[SERVER] || "https://#{tenant(credentials)}.live.dynatrace.com" - base_url = base_url.gsub('/communication', '').concat('/api').gsub(':8443', '').gsub(':443', '') - base_url + credentials = service['credentials'] + credentials[APIURL] || "https://#{credentials[ENVIRONMENTID]}.live.dynatrace.com/api" end def application_id @@ -143,26 +144,12 @@ def host_id "#{@application.details['application_name']}_${CF_INSTANCE_INDEX}" end - def server(credentials) - given_endp = credentials[ENDPOINT] || credentials[SERVER] || "https://#{tenant(credentials)}.live.dynatrace.com" - supports_apitoken? ? server_from_api : given_endp - end - - def server_from_api - endpoints = JSON.parse(File.read(@droplet.sandbox + 'manifest.json'))['communicationEndpoints'] - endpoints.join('\;') - end - - def tenant(credentials) - credentials[ENVIRONMENTID] || credentials[TENANT] - end - - def tenanttoken(credentials) - supports_apitoken? ? tenanttoken_from_api : credentials[TENANTTOKEN] + def tenanttoken + JSON.parse(File.read(@droplet.sandbox + 'manifest.json'))['tenantToken'] end - def tenanttoken_from_api - JSON.parse(File.read(@droplet.sandbox + 'manifest.json'))['tenantToken'] + def endpoints + '"' + JSON.parse(File.read(@droplet.sandbox + 'manifest.json'))['communicationEndpoints'].join(';') + '"' end def unpack_agent(root) diff --git a/spec/fixtures/framework_dynatrace_one_agent/.java-buildpack/dynatrace_one_agent/manifest.json b/spec/fixtures/framework_dynatrace_one_agent/.java-buildpack/dynatrace_one_agent/manifest.json index 234870abf1..a2c5ae6e8c 100644 --- a/spec/fixtures/framework_dynatrace_one_agent/.java-buildpack/dynatrace_one_agent/manifest.json +++ b/spec/fixtures/framework_dynatrace_one_agent/.java-buildpack/dynatrace_one_agent/manifest.json @@ -1,4 +1,14 @@ { + "technologies" : { + "java" : { + "linux-x86-64" : [ + { + "path": "agent/lib64/liboneagentloader.so", + "binarytype" : "loader" + } + ] + } + }, "version" : "1.105.147.20160930-153457", "tenantUUID" : "tenant", "tenantToken" : "token-from-file", diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 187e14a1c7..29783b3852 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -21,21 +21,22 @@ describe JavaBuildpack::Framework::DynatraceOneAgent do include_context 'component_helper' - it 'does not detect without dynatrace|ruxit-n/a service' do + it 'does not detect without dynatrace-n/a service' do expect(component.detect).to be_nil end context do before do - allow(services).to receive(:one_service?).with(/ruxit|dynatrace/, %w[environmentid tenant], - %w[apitoken tenanttoken]).and_return(true) - allow(services).to receive(:find_service).and_return('credentials' => { 'apitoken' => 'test-apitoken', - 'tenant' => 'test-tenant', - 'server' => 'test-server' }) + services << { 'name' => 'dynatrace-real', 'credentials' => { 'environmentid' => 'test-environmentid', + 'apiurl' => 'test-apiurl', + 'apitoken' => 'test-apitoken' } } + services << { 'name' => 'dynatrace-tags', 'credentials' => { 'tag:sometag' => 'tag-value', + 'tag:othertag' => 'othertag-value' } } + # allow(File).to receive(:file?).and_return(true) allow(application_cache).to receive(:get) - .with('test-server/api/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&' \ + .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&' \ 'Api-Token=test-apitoken') .and_yield(Pathname.new('spec/fixtures/stub-dynatrace-one-agent.zip').open, false) end @@ -53,66 +54,42 @@ expect(sandbox + 'manifest.json').to exist end - it 'does update JAVA_OPTS with environmentid and apitoken', - app_fixture: 'framework_dynatrace_one_agent' do - allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-tenant', - 'apitoken' => 'test-apitoken' }) - component.release - - expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_one_agent/agent/lib64/' \ - 'liboneagentloader.so=server=https://endpoint1/communication\\;https://endpoint2/communication,' \ - 'tenant=test-tenant,tenanttoken=token-from-file') - end - - it 'updates JAVA_OPTS with custom server and deprecated tenanttoken', + it 'updates JAVA_OPTS with agent loader', app_fixture: 'framework_dynatrace_one_agent' do - allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-server', - 'tenant' => 'test-tenant', - 'tenanttoken' => 'test-token' }) - component.release - - expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_one_agent/agent/lib64/' \ - 'liboneagentloader.so=server=test-server,tenant=test-tenant,' \ - 'tenanttoken=test-token') - end - it 'updates JAVA_OPTS with custom server and apitoken', - app_fixture: 'framework_dynatrace_one_agent' do - allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-server', - 'environmentid' => 'test-tenant', - 'apitoken' => 'test-apitoken' }) component.release expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_one_agent/agent/lib64/' \ - 'liboneagentloader.so=server=https://endpoint1/communication\\;https://endpoint2/communication,' \ - 'tenant=test-tenant,tenanttoken=token-from-file') + 'liboneagentloader.so') end it 'updates environment variables', app_fixture: 'framework_dynatrace_one_agent' do - allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-tenant', - 'apitoken' => 'test-apitoken' }) + component.release - expect(environment_variables).to include('RUXIT_APPLICATIONID=test-application-name') - expect(environment_variables).to include('RUXIT_HOST_ID=test-application-name_${CF_INSTANCE_INDEX}') + expect(environment_variables).to include('DT_APPLICATIONID=test-application-name') + expect(environment_variables).to include('DT_HOST_ID=test-application-name_${CF_INSTANCE_INDEX}') + expect(environment_variables).to include('DT_TENANT=test-environmentid') + expect(environment_variables).to include('DT_TENANTTOKEN=token-from-file') + expect(environment_variables).to include('DT_CONNECTION_POINT=' \ + '"https://endpoint1/communication;https://endpoint2/communication"') end context do let(:environment) do - { 'RUXIT_APPLICATIONID' => 'test-application-id', - 'RUXIT_HOST_ID' => 'test-host-id' } + { 'DT_APPLICATIONID' => 'test-application-id', + 'DT_HOST_ID' => 'test-host-id' } end it 'does not update environment variables if they exist', app_fixture: 'framework_dynatrace_one_agent' do - allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-tenant', - 'apitoken' => 'test-apitoken' }) + component.release - expect(environment_variables).not_to include(/RUXIT_APPLICATIONID/) - expect(environment_variables).not_to include(/RUXIT_HOST_ID/) + expect(environment_variables).not_to include(/DT_APPLICATIONID/) + expect(environment_variables).not_to include(/DT_HOST_ID/) end end From edf611ed72327262eb16dac023c6551605b68d36 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 19 Sep 2017 10:12:56 -0700 Subject: [PATCH 360/812] Polishing This change polishes up the contributed code. It removes some redundant behavior and organizes the code slightly different. [resolves #487] --- docs/framework-dynatrace_one_agent.md | 2 +- java-buildpack.iml | 57 ++++++------ .../framework/dynatrace_one_agent.rb | 93 +++++++++---------- .../framework/dynatrace_one_agent_spec.rb | 10 +- 4 files changed, 78 insertions(+), 84 deletions(-) diff --git a/docs/framework-dynatrace_one_agent.md b/docs/framework-dynatrace_one_agent.md index a50456fcc2..4580bb2e3e 100644 --- a/docs/framework-dynatrace_one_agent.md +++ b/docs/framework-dynatrace_one_agent.md @@ -25,9 +25,9 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- -| `environmentid` | Your Dynatrace environment ID is the unique identifier of your Dynatrace environment. You can find it in the deploy Dynatrace section within your environment. | `apitoken` | The token for integrating your Dynatrace environment with Cloud Foundry. You can find it in the deploy Dynatrace section within your environment. | `apiurl` | (Optional) The base URL of the Dynatrace API. If you are using Dynatrace Managed you will need to set this property to `https:///e//api`. If you are using Dynatrace SaaS you don't need to set this property. +| `environmentid` | Your Dynatrace environment ID is the unique identifier of your Dynatrace environment. You can find it in the deploy Dynatrace section within your environment. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/java-buildpack.iml b/java-buildpack.iml index 4b07f0dde5..df0d76f182 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -265,35 +265,36 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 00cdc02558..4d7cf6a4cf 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -46,83 +46,70 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = service['credentials'] - - @droplet.java_opts.add_agentpath(agent_path) - - environment = @application.environment + credentials = @application.services.find_service(FILTER)['credentials'] environment_variables = @droplet.environment_variables + manifest = agent_manifest - unless environment.key?(DT_APPLICATION_ID) - environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) - end + @droplet.java_opts.add_agentpath(agent_path(manifest)) + + environment_variables + .add_environment_variable(DT_TENANT, credentials[ENVIRONMENTID]) + .add_environment_variable(DT_TENANTTOKEN, tenanttoken(manifest)) + .add_environment_variable(DT_CONNECTION_POINT, endpoints(manifest)) - environment_variables.add_environment_variable(DT_HOST_ID, host_id) unless environment.key?(DT_HOST_ID) - environment_variables.add_environment_variable(DT_TENANT, credentials[ENVIRONMENTID]) - environment_variables.add_environment_variable(DT_TENANTTOKEN, tenanttoken) - environment_variables.add_environment_variable(DT_CONNECTION_POINT, endpoints) + environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) unless application_id? + environment_variables.add_environment_variable(DT_HOST_ID, host_id) unless host_id? end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - !service.nil? + @application.services.one_service? FILTER, APITOKEN, ENVIRONMENTID end private - FILTER = /dynatrace/ + APIURL = 'apiurl'.freeze + + APITOKEN = 'apitoken'.freeze DT_APPLICATION_ID = 'DT_APPLICATIONID'.freeze + DT_CONNECTION_POINT = 'DT_CONNECTION_POINT'.freeze + DT_HOST_ID = 'DT_HOST_ID'.freeze DT_TENANT = 'DT_TENANT'.freeze DT_TENANTTOKEN = 'DT_TENANTTOKEN'.freeze - DT_CONNECTION_POINT = 'DT_CONNECTION_POINT'.freeze - - APITOKEN = 'apitoken'.freeze + ENVIRONMENTID = 'environmentid'.freeze - APIURL = 'apiurl'.freeze + FILTER = /dynatrace/ - ENVIRONMENTID = 'environmentid'.freeze + private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_HOST_ID, :DT_TENANT, + :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER - private_constant :FILTER, :DT_APPLICATION_ID, :DT_HOST_ID - private_constant :DT_TENANT, :DT_TENANTTOKEN, :DT_CONNECTION_POINT - private_constant :ENVIRONMENTID, :APITOKEN - - def service - candidates = @application.services.select do |candidate| - ( - candidate['name'] =~ FILTER || - candidate['label'] =~ FILTER || - candidate['tags'].any? { |tag| tag =~ FILTER } - ) && - candidate['credentials'][ENVIRONMENTID] && candidate['credentials'][APITOKEN] - end + def agent_download_url + credentials = @application.services.find_service(FILTER)['credentials'] + download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ + "&bitness=64&Api-Token=#{credentials[APITOKEN]}" + ['latest', download_uri] + end - candidates.one? ? candidates.first : nil + def agent_manifest + JSON.parse(File.read(@droplet.sandbox + 'manifest.json')) end - def agent_path - technologies = JSON.parse(File.read(@droplet.sandbox + 'manifest.json'))['technologies'] + def agent_path(manifest) + technologies = manifest['technologies'] java_binaries = technologies['java']['linux-x86-64'] - loader = java_binaries.find { |bin| bin['binarytype'] == 'loader' } + loader = java_binaries.find { |bin| bin['binarytype'] == 'loader' } @droplet.sandbox + loader['path'] end - def agent_download_url - credentials = service['credentials'] - download_uri = "#{api_base_url}/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&" - download_uri += "Api-Token=#{credentials[APITOKEN]}" - ['latest', download_uri] - end - - def api_base_url - credentials = service['credentials'] + def api_base_url(credentials) credentials[APIURL] || "https://#{credentials[ENVIRONMENTID]}.live.dynatrace.com/api" end @@ -130,6 +117,14 @@ def application_id @application.details['application_name'] end + def application_id? + @application.environment.key?(DT_APPLICATION_ID) + end + + def endpoints(manifest) + "\"#{manifest['communicationEndpoints'].join(';')}\"" + end + def expand(file) with_timing "Expanding Dynatrace OneAgent to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do Dir.mktmpdir do |root| @@ -144,12 +139,12 @@ def host_id "#{@application.details['application_name']}_${CF_INSTANCE_INDEX}" end - def tenanttoken - JSON.parse(File.read(@droplet.sandbox + 'manifest.json'))['tenantToken'] + def host_id? + @application.environment.key?(DT_HOST_ID) end - def endpoints - '"' + JSON.parse(File.read(@droplet.sandbox + 'manifest.json'))['communicationEndpoints'].join(';') + '"' + def tenanttoken(manifest) + manifest['tenantToken'] end def unpack_agent(root) diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 29783b3852..7d115d92f5 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -28,13 +28,11 @@ context do before do - services << { 'name' => 'dynatrace-real', 'credentials' => { 'environmentid' => 'test-environmentid', - 'apiurl' => 'test-apiurl', - 'apitoken' => 'test-apitoken' } } - services << { 'name' => 'dynatrace-tags', 'credentials' => { 'tag:sometag' => 'tag-value', - 'tag:othertag' => 'othertag-value' } } + allow(services).to receive(:one_service?).with(/dynatrace/, 'apitoken', 'environmentid').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-environmentid', + 'apiurl' => 'test-apiurl', + 'apitoken' => 'test-apitoken' }) - # allow(File).to receive(:file?).and_return(true) allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&' \ 'Api-Token=test-apitoken') From ec4123cfe1fc97b9810e34f0208f1544d66e3d35 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 6 Oct 2017 14:53:49 -0700 Subject: [PATCH 361/812] Configure StackDriver Debugger Previously the application name and version of an application debugged using Google Stackdriver Debugger were fixed to the name and version as defined by Cloud Foundry. While this is a great default case, there are reasons for overriding it. This change makes those values configurable. --- config/google_stackdriver_debugger.yml | 2 ++ .../framework/google_stackdriver_debugger.rb | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/config/google_stackdriver_debugger.yml b/config/google_stackdriver_debugger.yml index d79b3a1238..2a89634f69 100644 --- a/config/google_stackdriver_debugger.yml +++ b/config/google_stackdriver_debugger.yml @@ -17,3 +17,5 @@ --- version: 2.+ repository_root: "{default.repository.root}/google-stackdriver-debugger/{platform}/{architecture}" +application_name: +application_version: diff --git a/lib/java_buildpack/framework/google_stackdriver_debugger.rb b/lib/java_buildpack/framework/google_stackdriver_debugger.rb index 0045462420..a30687b971 100644 --- a/lib/java_buildpack/framework/google_stackdriver_debugger.rb +++ b/lib/java_buildpack/framework/google_stackdriver_debugger.rb @@ -39,8 +39,8 @@ def release .add_agentpath_with_props(@droplet.sandbox + 'cdbg_java_agent.so', '--logtostderr' => 1) .add_system_property('com.google.cdbg.auth.serviceaccount.enable', true) .add_system_property('com.google.cdbg.auth.serviceaccount.jsonfile', json_file) - .add_system_property('com.google.cdbg.module', @application.details['application_name']) - .add_system_property('com.google.cdbg.version', @application.details['application_version']) + .add_system_property('com.google.cdbg.module', application_name) + .add_system_property('com.google.cdbg.version', application_version) end protected @@ -58,6 +58,14 @@ def supports? private + def application_name + @configuration['application_name'] || @application.details['application_name'] + end + + def application_version + @configuration['application_version'] || @application.details['application_version'] + end + def json_file @droplet.sandbox + 'svc.json' end From ed12cde6167a4be216cdc45297c3a5e169717f11 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 6 Oct 2017 14:56:54 -0700 Subject: [PATCH 362/812] Polishing --- .idea/.rakeTasks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index d167d0de90..368e4e50f6 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> From 1a1faefb3449769c825e052272d34eed68564bcb Mon Sep 17 00:00:00 2001 From: Carlo Alberto Ferraris Date: Thu, 5 Oct 2017 07:45:17 +0200 Subject: [PATCH 363/812] Update Configuration Instructions Previously, the documentation for configuring the buildpack highlighted forking as the method to use. As this isn't true (and hasn't been for a while), this change reverse the order giving environment variable configuration prominence over forking. [#497] --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d44868ddbb..391d23d23f 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,7 @@ The following are _very_ simple examples for deploying the artifact types that w * [Spring Boot CLI](docs/example-spring_boot_cli.md) ## Configuration and Extension -The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. - -Buildpack configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack. The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec ([Wikipedia] has a good description of this yaml syntax). For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. +The buildpack default configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack (in this case you will have to extend the buildpack, see below). The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec ([Wikipedia] has a good description of this yaml syntax). For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. ```bash $ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ jre: { version: 1.7.0_+ }, memory_calculator: { stack_threads: 200 } }' @@ -57,7 +55,9 @@ env: See the [Environment Variables][] documentation for more information. -To learn how to configure various properties of the buildpack, follow the "Configuration" links below. More information on extending the buildpack is available [here](docs/extending.md). +To learn how to configure various properties of the buildpack, follow the "Configuration" links below. + +The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. More information on extending the buildpack is available [here](docs/extending.md). ## Additional Documentation * [Design](docs/design.md) From 0115c9358f99951799e79416bedac24f4165bd93 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 17 Oct 2017 11:23:19 -0700 Subject: [PATCH 364/812] Polishing [resolves #497] --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 391d23d23f..7e574a63ee 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The following are _very_ simple examples for deploying the artifact types that w * [Spring Boot CLI](docs/example-spring_boot_cli.md) ## Configuration and Extension -The buildpack default configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack (in this case you will have to extend the buildpack, see below). The value of the variable should be valid inline yaml, referred to as `flow style` in the yaml spec ([Wikipedia] has a good description of this yaml syntax). For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. +The buildpack default configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack (in this case you will have to extend the buildpack, see below). The value of the variable should be valid inline yaml, referred to as "flow style" in the yaml spec ([Wikipedia][] has a good description of this yaml syntax). For example, to change the default version of Java to 7 and adjust the memory heuristics apply this environment variable to the application. ```bash $ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ jre: { version: 1.7.0_+ }, memory_calculator: { stack_threads: 200 } }' @@ -55,7 +55,7 @@ env: See the [Environment Variables][] documentation for more information. -To learn how to configure various properties of the buildpack, follow the "Configuration" links below. +To learn how to configure various properties of the buildpack, follow the "Configuration" links below. The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. More information on extending the buildpack is available [here](docs/extending.md). From 88b210e1c68740a05525179029a33925a2c2f632 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 17 Oct 2017 12:48:29 -0700 Subject: [PATCH 365/812] One Service With Credentials Previously, the Services.one_service? method ensured first that there was a single service that matched and then ensured that the credentials of that service matched. This was more restrictive than it needed to be, so this change loosens things a bit such that it now enforces only a single service that matches name, label, tags, and required credentials. [resolves #489] --- .idea/runConfigurations/All_Tests__2_2_.xml | 6 +- .idea/runConfigurations/All_Tests__2_3_.xml | 2 +- .idea/runConfigurations/All_Tests__2_4_.xml | 2 +- .../Without_Integration_Tests__2_2_.xml | 6 +- .../Without_Integration_Tests__2_3_.xml | 2 +- .../Without_Integration_Tests__2_4_.xml | 2 +- lib/java_buildpack/component/services.rb | 80 ++-- .../container/tomcat/tomcat_geode_store.rb | 4 +- .../container/tomcat/tomcat_redis_store.rb | 3 +- .../framework/app_dynamics_agent.rb | 2 +- .../framework/contrast_security_agent.rb | 9 +- .../framework/dyadic_ekm_security_provider.rb | 3 +- .../framework/dynatrace_one_agent.rb | 2 +- .../framework/google_stackdriver_debugger.rb | 2 +- .../framework/introscope_agent.rb | 2 +- .../java_memory_assistant/heap_dump_folder.rb | 2 +- .../framework/luna_security_provider.rb | 2 +- lib/java_buildpack/framework/metric_writer.rb | 2 +- .../framework/new_relic_agent.rb | 2 +- .../protect_app_security_provider.rb | 2 +- .../framework/spring_insight.rb | 2 +- lib/java_buildpack/framework/takipi_agent.rb | 2 +- lib/java_buildpack/jre/jvmkill_agent.rb | 2 +- .../java_buildpack/component/services_spec.rb | 416 +++++++++++++----- .../heap_dump_folder_spec.rb | 32 +- spec/java_buildpack/jre/jvmkill_agent_spec.rb | 2 +- 26 files changed, 407 insertions(+), 186 deletions(-) diff --git a/.idea/runConfigurations/All_Tests__2_2_.xml b/.idea/runConfigurations/All_Tests__2_2_.xml index 0f31a50950..d268e3da49 100644 --- a/.idea/runConfigurations/All_Tests__2_2_.xml +++ b/.idea/runConfigurations/All_Tests__2_2_.xml @@ -4,13 +4,13 @@ - - + + - + diff --git a/.idea/runConfigurations/All_Tests__2_3_.xml b/.idea/runConfigurations/All_Tests__2_3_.xml index 16757fc1af..b5f8fc31ff 100644 --- a/.idea/runConfigurations/All_Tests__2_3_.xml +++ b/.idea/runConfigurations/All_Tests__2_3_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_4_.xml b/.idea/runConfigurations/All_Tests__2_4_.xml index 02bfb110fc..a28ec423a3 100644 --- a/.idea/runConfigurations/All_Tests__2_4_.xml +++ b/.idea/runConfigurations/All_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml index c700635527..b24c428bcf 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml @@ -4,13 +4,13 @@ - - + + - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml index e1ba536bb0..2332d91353 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml index 567a5e49a4..6e2a813de3 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/lib/java_buildpack/component/services.rb b/lib/java_buildpack/component/services.rb index 0953320eac..8c484d4cda 100644 --- a/lib/java_buildpack/component/services.rb +++ b/lib/java_buildpack/component/services.rb @@ -14,7 +14,6 @@ # limitations under the License. require 'java_buildpack/component' -require 'java_buildpack/logging/logger_factory' module JavaBuildpack module Component @@ -29,12 +28,25 @@ def initialize(raw) end # Compares the name, label, and tags of each service to the given +filter+. The method returns the first service - # that the +filter+ matches. If no service matches, returns +nil+ + # that the +filter+ matches. If no service matches, returns +nil+. + # + # @param [Regexp, String] filter a +RegExp+ or +String+ to match against the name, label, and tags of the services + # @param [String] required_credentials an optional list of keys or groups of keys, where at least one key from the + # group, must exist in the credentials payload of the candidate service + # @return [Hash, nil] the first service that +filter+ matches. If no service matches, returns +nil+. + def find_service(filter, *required_credentials) + select(&service?(filter)) + .find(&credentials?(required_credentials)) + end + + # Compares the name, label, and tags of each service to the given +filter+. The method returns the first service + # that +filter+ matches. If no service matches, returns +nil+. # # @param [Regexp, String] filter a +RegExp+ or +String+ to match against the name, label, and tags of the services # @return [Hash, nil] the first service that +filter+ matches. If no service matches, returns +nil+. - def find_service(filter) - find(&matcher(filter)) + def find_volume_service(filter) + select(&service?(filter)) + .find(&volume_mount?) end # Compares the name, label, and tags of each service to the given +filter+. The method returns +true+ if the @@ -46,58 +58,46 @@ def find_service(filter) # @return [Boolean] +true+ if the +filter+ matches exactly one service with the required credentials, +false+ # otherwise. def one_service?(filter, *required_credentials) - candidates = select(&matcher(filter)) - - match = false - if candidates.one? - if credentials?(candidates.first['credentials'], required_credentials) - match = true - else - logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger Services - logger.debug do - "A service with a name label or tag matching #{filter} was found, but was missing one of the required" \ - " credentials #{required_credentials}" - end - end - end - - match + select(&service?(filter)) + .select(&credentials?(required_credentials)) + .one? end - # Compares the name, lavel,a nd tags of each service to the given +filter+. The method returns +true+ if the + # Compares the name, label, and tags of each service to the given +filter+. The method returns +true+ if the # +filter+ matches exactly one volume service, +false+ otherwise. # # @param [Regexp, String] filter a +RegExp+ or +String+ to match against the name, label, and tags of the services # @return [Boolean] +true+ if the +filter+ matches exactly one volume service with the required credentials, # +false+ otherwise. def one_volume_service?(filter) - candidates = select(&matcher(filter)) - - match = false - if candidates.one? - volume_mounts = candidates.first['volume_mounts'] - if !volume_mounts.nil? - match = volume_mounts.one? - else - logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger Services - logger.debug do - "A service with a name label or tag matching #{filter} was found, but was missing a volume_mount" - end + select(&service?(filter)) + .select(&volume_mount?) + .one? + end + + private + + def credentials?(required_keys) + lambda do |service| + credentials = service['credentials'] + return false if credentials.nil? + + required_keys.all? do |k| + k.is_a?(Array) ? k.any? { |g| credentials.key?(g) } : credentials.key?(k) end end - - match end - private + def volume_mount? + lambda do |service| + volume_mounts = service['volume_mounts'] + return false if volume_mounts.nil? - def credentials?(candidate, required_keys) - required_keys.all? do |k| - k.is_a?(Array) ? k.any? { |g| candidate.key?(g) } : candidate.key?(k) + volume_mounts.one? end end - def matcher(filter) + def service?(filter) filter = Regexp.new(filter) unless filter.is_a?(Regexp) lambda do |service| diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index b42fab975f..aec5594dbc 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -37,7 +37,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release return unless supports? - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, KEY_LOCATORS, KEY_USERS)['credentials'] user = credentials[KEY_USERS].find { |u| u['username'] == 'cluster_operator' } @droplet.java_opts.add_system_property 'gemfire.security-username', 'cluster_operator' @@ -108,7 +108,7 @@ def add_listener(server) end def add_locators(pool) - service = @application.services.find_service FILTER + service = @application.services.find_service FILTER, KEY_LOCATORS, KEY_USERS service['credentials']['locators'].each do |locator| match_info = LOCATOR_REGEXP.match(locator) pool.add_element 'locator', diff --git a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb index a1eb8a74da..084d3f9493 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb @@ -70,7 +70,8 @@ def add_manager(context) end def add_store(manager) - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, [KEY_HOST_NAME, KEY_HOST], KEY_PORT, + KEY_PASSWORD)['credentials'] manager.add_element 'Store', 'className' => REDIS_STORE_CLASS_NAME, diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index c39b317510..b6b87595b4 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -31,7 +31,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, 'host-name')['credentials'] java_opts = @droplet.java_opts java_opts.add_javaagent(@droplet.sandbox + 'javaagent.jar') diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index 7c9b224c68..297f485ffa 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -33,7 +33,8 @@ def compile download_jar @droplet.copy_resources - write_configuration @application.services.find_service(CONTRAST_FILTER)['credentials'] + write_configuration @application.services.find_service(FILTER, API_KEY, SERVICE_KEY, TEAMSERVER_URL, + USERNAME)['credentials'] end # (see JavaBuildpack::Component::BaseComponent#release) @@ -54,14 +55,14 @@ def jar_name # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service?(CONTRAST_FILTER, API_KEY, SERVICE_KEY, TEAMSERVER_URL, USERNAME) + @application.services.one_service? FILTER, API_KEY, SERVICE_KEY, TEAMSERVER_URL, USERNAME end private API_KEY = 'api_key'.freeze - CONTRAST_FILTER = 'contrast-security'.freeze + FILTER = 'contrast-security'.freeze INFLECTION_VERSION = JavaBuildpack::Util::TokenizedVersion.new('3.4.3').freeze @@ -73,7 +74,7 @@ def supports? USERNAME = 'username'.freeze - private_constant :API_KEY, :CONTRAST_FILTER, :INFLECTION_VERSION, :PLUGIN_PACKAGE, :SERVICE_KEY, :TEAMSERVER_URL, + private_constant :API_KEY, :FILTER, :INFLECTION_VERSION, :PLUGIN_PACKAGE, :SERVICE_KEY, :TEAMSERVER_URL, :USERNAME def add_contrast(doc, credentials) diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index ddb8f5fc2c..ebf240e4a5 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -33,7 +33,8 @@ def compile @droplet.copy_resources @droplet.security_providers << 'com.dyadicsec.provider.DYCryptoProvider' - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, 'ca', 'key', 'recv_timeout', 'retries', 'send_timeout', + 'servers')['credentials'] write_key credentials['key'] write_cert credentials['ca'] write_conf credentials['servers'], credentials['send_timeout'], credentials['recv_timeout'], diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 4d7cf6a4cf..a8920b784f 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -92,7 +92,7 @@ def supports? :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER def agent_download_url - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, APITOKEN, ENVIRONMENTID)['credentials'] download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ "&bitness=64&Api-Token=#{credentials[APITOKEN]}" ['latest', download_uri] diff --git a/lib/java_buildpack/framework/google_stackdriver_debugger.rb b/lib/java_buildpack/framework/google_stackdriver_debugger.rb index a30687b971..6e3f55e8c8 100644 --- a/lib/java_buildpack/framework/google_stackdriver_debugger.rb +++ b/lib/java_buildpack/framework/google_stackdriver_debugger.rb @@ -27,7 +27,7 @@ class GoogleStackdriverDebugger < JavaBuildpack::Component::VersionedDependencyC def compile download_tar false - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, PRIVATE_KEY_DATA)['credentials'] write_json_file credentials[PRIVATE_KEY_DATA] end diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index 19df64fc7a..291f58c3cc 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -32,7 +32,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, 'url')['credentials'] java_opts = @droplet.java_opts java_opts diff --git a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb index 2e305fefab..04f92cb1e2 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb @@ -71,7 +71,7 @@ def release FILTER = 'heap-dump'.freeze def find_heap_dump_volume_service - @application.services.find_service FILTER + @application.services.find_volume_service FILTER end def default_heap_dump_folder diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 1c18e97a2f..435728804a 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -33,7 +33,7 @@ def compile @droplet.copy_resources @droplet.security_providers << 'com.safenetinc.luna.provider.LunaProvider' - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, 'client', 'servers', 'groups')['credentials'] write_client credentials['client'] write_servers credentials['servers'] write_configuration credentials['servers'], credentials['groups'] diff --git a/lib/java_buildpack/framework/metric_writer.rb b/lib/java_buildpack/framework/metric_writer.rb index a2ace91cc5..084c24b14d 100644 --- a/lib/java_buildpack/framework/metric_writer.rb +++ b/lib/java_buildpack/framework/metric_writer.rb @@ -30,7 +30,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, ACCESS_KEY, ENDPOINT)['credentials'] @droplet.additional_libraries << (@droplet.sandbox + jar_name) @droplet.java_opts diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 06fcf9b847..8e51ccb133 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -30,7 +30,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, [LICENSE_KEY, LICENSE_KEY_USER])['credentials'] java_opts = @droplet.java_opts configuration = {} diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb index da1af66ba8..719bf22c30 100644 --- a/lib/java_buildpack/framework/protect_app_security_provider.rb +++ b/lib/java_buildpack/framework/protect_app_security_provider.rb @@ -34,7 +34,7 @@ def compile @droplet.copy_resources @droplet.security_providers << 'com.ingrian.security.nae.IngrianProvider' - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, 'client', 'trusted_certificates')['credentials'] pkcs12 = merge_client_credentials credentials['client'] add_client_credentials pkcs12 diff --git a/lib/java_buildpack/framework/spring_insight.rb b/lib/java_buildpack/framework/spring_insight.rb index 4dbc081399..edfe47a50f 100644 --- a/lib/java_buildpack/framework/spring_insight.rb +++ b/lib/java_buildpack/framework/spring_insight.rb @@ -139,7 +139,7 @@ def init_weaver(root) end def find_insight_agent - service = @application.services.find_service FILTER + service = @application.services.find_service FILTER, 'agent_download_url', 'service_instance_id' credentials = service['credentials'] version = credentials['version'] || '1.0.0' uri = credentials['agent_download_url'] diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index 3651b87da6..b4524fa243 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -45,7 +45,7 @@ def release .add_environment_variable('TAKIPI_HOME', @droplet.sandbox) .add_environment_variable('TAKIPI_MACHINE_NAME', node_name) - config_env_vars @application.services.find_service(FILTER)['credentials'] + config_env_vars @application.services.find_service(FILTER, [SECRET_KEY, COLLECTOR_HOST])['credentials'] end protected diff --git a/lib/java_buildpack/jre/jvmkill_agent.rb b/lib/java_buildpack/jre/jvmkill_agent.rb index 33f15a789b..6126aec7eb 100644 --- a/lib/java_buildpack/jre/jvmkill_agent.rb +++ b/lib/java_buildpack/jre/jvmkill_agent.rb @@ -61,7 +61,7 @@ def application_identifier end def container_dir - @application.services.find_service(FILTER)['volume_mounts'].first['container_dir'] + @application.services.find_volume_service(FILTER)['volume_mounts'].first['container_dir'] end def heap_dump_path diff --git a/spec/java_buildpack/component/services_spec.rb b/spec/java_buildpack/component/services_spec.rb index 1f9d5e2fe0..2a144f17b9 100644 --- a/spec/java_buildpack/component/services_spec.rb +++ b/spec/java_buildpack/component/services_spec.rb @@ -20,141 +20,359 @@ describe JavaBuildpack::Component::Services do include_context 'logging_helper' - let(:service) do - { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } } - end + let(:services) { described_class.new('test' => service_payload) } - let(:services) { described_class.new('test' => [service]) } + context('find_service') do - it 'returns false from one_service? if there is no service that matches' do - expect(services.one_service?('bad-test')).not_to be - expect(services.one_service?(/bad-test/)).not_to be - end + context('single service') do - it 'returns true from one_service? if there is a matching name' do - expect(services.one_service?('test-name')).to be - expect(services.one_service?(/test-name/)).to be - end + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] + end - it 'returns true from one_service? if there is a matching label' do - expect(services.one_service?('test-label')).to be - expect(services.one_service?(/test-label/)).to be - end + it 'returns nil from find_service? if there is no service that matches' do + expect(services.find_service('bad-test')).to be_nil + expect(services.find_service(/bad-test/)).to be_nil + end - it 'returns true from one_service? if there is a matching tag' do - expect(services.one_service?('test-tag')).to be - expect(services.one_service?(/test-tag/)).to be - end + it 'returns service from find_service? if there is a matching name' do + expect(services.find_service('test-name')).to be(service_payload[0]) + expect(services.find_service(/test-name/)).to be(service_payload[0]) + end - it 'returns false from one_service? if there is a matching service without required credentials' do - expect(services.one_service?('test-tag', 'bad-credential')).not_to be - expect(services.one_service?(/test-tag/, 'bad-credential')).not_to be - end + it 'returns service from find_service? if there is a matching label' do + expect(services.find_service('test-label')).to be(service_payload[0]) + expect(services.find_service(/test-label/)).to be(service_payload[0]) + end - it 'returns true from one_service? if there is a matching service with required credentials' do - expect(services.one_service?('test-tag', 'uri')).to be - expect(services.one_service?(/test-tag/, 'uri')).to be - end + it 'returns service from find_service? if there is a matching tag' do + expect(services.find_service('test-tag')).to be(service_payload[0]) + expect(services.find_service(/test-tag/)).to be(service_payload[0]) + end - it 'returns true from one_service? if there is a matching service with one required group credentials' do - expect(services.one_service?('test-tag', %w[uri other])).to be - expect(services.one_service?(/test-tag/, %w[uri other])).to be - end + end - it 'returns true from one_service? if there is a matching service with two required group credentials' do - expect(services.one_service?('test-tag', %w[h1 h2])).to be - expect(services.one_service?(/test-tag/, %w[h1 h2])).to be - end + context('two services') do - it 'returns false from one_service? if there is a matching service with no required group credentials' do - expect(services.one_service?('test-tag', %w[foo bar])).not_to be - expect(services.one_service?(/test-tag/, %w[foo bar])).not_to be - end + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan' }, + { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] + end - it 'returns true from one_volume_service? if there is a matching name and no volume_mounts' do - expect(services.one_volume_service?('test-name')).not_to be - expect(services.one_volume_service?(/test-name/)).not_to be - end + it 'returns nil from find_service? if there is no service that matches' do + expect(services.find_service('bad-test')).to be_nil + expect(services.find_service(/bad-test/)).to be_nil + end - it 'returns true from one_volume_service? if there is a matching label and no volume_mounts' do - expect(services.one_volume_service?('test-label')).not_to be - expect(services.one_volume_service?(/test-label/)).not_to be - end + it 'returns service from find_service? if there is a matching name' do + expect(services.find_service('test-name')).to be(service_payload[1]) + expect(services.find_service(/test-name/)).to be(service_payload[1]) + end + + it 'returns service from find_service? if there is a matching label' do + expect(services.find_service('test-label')).to be(service_payload[1]) + expect(services.find_service(/test-label/)).to be(service_payload[1]) + end + + it 'returns service from find_service? if there is a matching tag' do + expect(services.find_service('test-tag')).to be(service_payload[1]) + expect(services.find_service(/test-tag/)).to be(service_payload[1]) + end + + end - it 'returns false from one_volume_service? if there is a matching tag and no volume_mounts' do - expect(services.one_volume_service?('test-tag')).not_to be - expect(services.one_volume_service?(/test-tag/)).not_to be end - context do - let(:service) do - { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, - 'volume_mounts' => [] } + context('find_volume_service') do + + context('single service') do + + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', + 'device_type' => 'shared', + 'mode' => 'rw' }] }] + end + + it 'returns nil from find_service? if there is no service that matches' do + expect(services.find_volume_service('bad-test')).to be_nil + expect(services.find_volume_service(/bad-test/)).to be_nil + end + + it 'returns service from find_service? if there is a matching name' do + expect(services.find_volume_service('test-name')).to be(service_payload[0]) + expect(services.find_volume_service(/test-name/)).to be(service_payload[0]) + end + + it 'returns service from find_service? if there is a matching label' do + expect(services.find_volume_service('test-label')).to be(service_payload[0]) + expect(services.find_volume_service(/test-label/)).to be(service_payload[0]) + end + + it 'returns service from find_service? if there is a matching tag' do + expect(services.find_volume_service('test-tag')).to be(service_payload[0]) + expect(services.find_volume_service(/test-tag/)).to be(service_payload[0]) + end + end - it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do - expect(services.one_volume_service?('test-name')).not_to be - expect(services.one_volume_service?(/test-name/)).not_to be + context('two services') do + + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + 'volume_mounts' => [] }, + { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', + 'device_type' => 'shared', + 'mode' => 'rw' }] }] + end + + it 'returns nil from find_service? if there is no service that matches' do + expect(services.find_volume_service('bad-test')).to be_nil + expect(services.find_volume_service(/bad-test/)).to be_nil + end + + it 'returns service from find_service? if there is a matching name' do + expect(services.find_volume_service('test-name')).to be(service_payload[1]) + expect(services.find_volume_service(/test-name/)).to be(service_payload[1]) + end + + it 'returns service from find_service? if there is a matching label' do + expect(services.find_volume_service('test-label')).to be(service_payload[1]) + expect(services.find_volume_service(/test-label/)).to be(service_payload[1]) + end + + it 'returns service from find_service? if there is a matching tag' do + expect(services.find_volume_service('test-tag')).to be(service_payload[1]) + expect(services.find_volume_service(/test-tag/)).to be(service_payload[1]) + end + end - it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do - expect(services.one_volume_service?('test-label')).not_to be - expect(services.one_volume_service?(/test-label/)).not_to be + end + + context('one_service') do + + context('single service') do + + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] + end + + it 'returns false from one_service? if there is no service that matches' do + expect(services.one_service?('bad-test')).not_to be + expect(services.one_service?(/bad-test/)).not_to be + end + + it 'returns true from one_service? if there is a matching name' do + expect(services.one_service?('test-name')).to be + expect(services.one_service?(/test-name/)).to be + end + + it 'returns true from one_service? if there is a matching label' do + expect(services.one_service?('test-label')).to be + expect(services.one_service?(/test-label/)).to be + end + + it 'returns true from one_service? if there is a matching tag' do + expect(services.one_service?('test-tag')).to be + expect(services.one_service?(/test-tag/)).to be + end + + it 'returns false from one_service? if there is a matching service without required credentials' do + expect(services.one_service?('test-tag', 'bad-credential')).not_to be + expect(services.one_service?(/test-tag/, 'bad-credential')).not_to be + end + + it 'returns true from one_service? if there is a matching service with required credentials' do + expect(services.one_service?('test-tag', 'uri')).to be + expect(services.one_service?(/test-tag/, 'uri')).to be + end + + it 'returns true from one_service? if there is a matching service with one required group credentials' do + expect(services.one_service?('test-tag', %w[uri other])).to be + expect(services.one_service?(/test-tag/, %w[uri other])).to be + end + + it 'returns true from one_service? if there is a matching service with two required group credentials' do + expect(services.one_service?('test-tag', %w[h1 h2])).to be + expect(services.one_service?(/test-tag/, %w[h1 h2])).to be + end + + it 'returns false from one_service? if there is a matching service with no required group credentials' do + expect(services.one_service?('test-tag', %w[foo bar])).not_to be + expect(services.one_service?(/test-tag/, %w[foo bar])).not_to be + end + end - it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do - expect(services.one_volume_service?('test-tag')).not_to be - expect(services.one_volume_service?(/test-tag/)).not_to be + context('two services') do + + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan' }, + { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] + end + + it 'returns false from one_service? if there is no service that matches' do + expect(services.one_service?('bad-test')).not_to be + expect(services.one_service?(/bad-test/)).not_to be + end + + it 'returns true from one_service? if there is a matching name' do + expect(services.one_service?('test-name')).to be + expect(services.one_service?(/test-name/)).to be + end + + it 'returns true from one_service? if there is a matching label' do + expect(services.one_service?('test-label')).to be + expect(services.one_service?(/test-label/)).to be + end + + it 'returns true from one_service? if there is a matching tag' do + expect(services.one_service?('test-tag')).to be + expect(services.one_service?(/test-tag/)).to be + end + + it 'returns false from one_service? if there is a matching service without required credentials' do + expect(services.one_service?('test-tag', 'bad-credential')).not_to be + expect(services.one_service?(/test-tag/, 'bad-credential')).not_to be + end + + it 'returns true from one_service? if there is a matching service with required credentials' do + expect(services.one_service?('test-tag', 'uri')).to be + expect(services.one_service?(/test-tag/, 'uri')).to be + end + + it 'returns true from one_service? if there is a matching service with one required group credentials' do + expect(services.one_service?('test-tag', %w[uri other])).to be + expect(services.one_service?(/test-tag/, %w[uri other])).to be + end + + it 'returns true from one_service? if there is a matching service with two required group credentials' do + expect(services.one_service?('test-tag', %w[h1 h2])).to be + expect(services.one_service?(/test-tag/, %w[h1 h2])).to be + end + + it 'returns false from one_service? if there is a matching service with no required group credentials' do + expect(services.one_service?('test-tag', %w[foo bar])).not_to be + expect(services.one_service?(/test-tag/, %w[foo bar])).not_to be + end + end end - context do - let(:service) do - { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, - 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', - 'device_type' => 'shared', - 'mode' => 'rw' }] } - end + context('one_volume_service') do + + context('no volume mounts') do + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] + end + + it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do + expect(services.one_volume_service?('test-name')).not_to be + expect(services.one_volume_service?(/test-name/)).not_to be + end + + it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do + expect(services.one_volume_service?('test-label')).not_to be + expect(services.one_volume_service?(/test-label/)).not_to be + end + + it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do + expect(services.one_volume_service?('test-tag')).not_to be + expect(services.one_volume_service?(/test-tag/)).not_to be + end - it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do - expect(services.one_volume_service?('test-name')).to be - expect(services.one_volume_service?(/test-name/)).to be end - it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do - expect(services.one_volume_service?('test-label')).to be - expect(services.one_volume_service?(/test-label/)).to be + context('empty volume mounts') do + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + 'volume_mounts' => [] }] + end + + it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do + expect(services.one_volume_service?('test-name')).not_to be + expect(services.one_volume_service?(/test-name/)).not_to be + end + + it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do + expect(services.one_volume_service?('test-label')).not_to be + expect(services.one_volume_service?(/test-label/)).not_to be + end + + it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do + expect(services.one_volume_service?('test-tag')).not_to be + expect(services.one_volume_service?(/test-tag/)).not_to be + end + end - it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do - expect(services.one_volume_service?('test-tag')).to be - expect(services.one_volume_service?(/test-tag/)).to be + context('one volume mount') do + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', + 'device_type' => 'shared', + 'mode' => 'rw' }] }] + end + + it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do + expect(services.one_volume_service?('test-name')).to be + expect(services.one_volume_service?(/test-name/)).to be + end + + it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do + expect(services.one_volume_service?('test-label')).to be + expect(services.one_volume_service?(/test-label/)).to be + end + + it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do + expect(services.one_volume_service?('test-tag')).to be + expect(services.one_volume_service?(/test-tag/)).to be + end + end - end + context('two volume mounts') do + let(:service_payload) do + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', + 'device_type' => 'shared', + 'mode' => 'rw' }, + { 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', + 'device_type' => 'shared', + 'mode' => 'rw' }] }] + end - it 'returns nil from find_service? if there is no service that matches' do - expect(services.find_service('bad-test')).to be_nil - expect(services.find_service(/bad-test/)).to be_nil - end + it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do + expect(services.one_volume_service?('test-name')).not_to be + expect(services.one_volume_service?(/test-name/)).not_to be + end - it 'returns service from find_service? if there is a matching name' do - expect(services.find_service('test-name')).to be(service) - expect(services.find_service(/test-name/)).to be(service) - end + it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do + expect(services.one_volume_service?('test-label')).not_to be + expect(services.one_volume_service?(/test-label/)).not_to be + end - it 'returns service from find_service? if there is a matching label' do - expect(services.find_service('test-label')).to be(service) - expect(services.find_service(/test-label/)).to be(service) - end + it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do + expect(services.one_volume_service?('test-tag')).not_to be + expect(services.one_volume_service?(/test-tag/)).not_to be + end + + end - it 'returns service from find_service? if there is a matching tag' do - expect(services.find_service('test-tag')).to be(service) - expect(services.find_service(/test-tag/)).to be(service) end end diff --git a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb index 36613185ac..62c8ce1968 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb @@ -81,14 +81,14 @@ end before do - allow(services).to receive(:find_service).with('heap-dump') - .and_return('volume_mounts' => - [ - { - 'container_dir' => '/my_volume', - 'mode' => 'rw' - } - ]) + allow(services).to receive(:find_volume_service).with('heap-dump') + .and_return('volume_mounts' => + [ + { + 'container_dir' => '/my_volume', + 'mode' => 'rw' + } + ]) end it 'adds \'jma.heap_dump_folder\' with volume container_dir as path root', :enable_log_file, log_level: 'INFO' do @@ -111,14 +111,14 @@ end before do - allow(services).to receive(:find_service).with('heap-dump') - .and_return('volume_mounts' => - [ - { - 'container_dir' => '/my_volume', - 'mode' => 'r' - } - ]) + allow(services).to receive(:find_volume_service).with('heap-dump') + .and_return('volume_mounts' => + [ + { + 'container_dir' => '/my_volume', + 'mode' => 'r' + } + ]) end it 'fails if volume does not have write mode active', :enable_log_file, log_level: 'DEBUG' do diff --git a/spec/java_buildpack/jre/jvmkill_agent_spec.rb b/spec/java_buildpack/jre/jvmkill_agent_spec.rb index 7bd160c741..762cafb7d9 100644 --- a/spec/java_buildpack/jre/jvmkill_agent_spec.rb +++ b/spec/java_buildpack/jre/jvmkill_agent_spec.rb @@ -44,7 +44,7 @@ it 'adds heap dump parameter to JAVA_OPTS when volume service available' do allow(services).to receive(:one_volume_service?).with(/heap-dump/).and_return(true) - allow(services).to receive(:find_service).and_return('volume_mounts' => + allow(services).to receive(:find_volume_service).and_return('volume_mounts' => [{ 'container_dir' => 'test-container-dir' }]) component.release From d1a07f8e5a742cefbe4e49dd9b6f331a97f138d2 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 18 Oct 2017 09:13:50 -0700 Subject: [PATCH 366/812] Missed Improved find_service() Call Previously, a change went in that allowed find_service() to take a collection of required credential keys. That changed missed one place where the improvement could have been made. This change finishes that missed improvement. [#489] --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index a8920b784f..6ca3014de6 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -46,7 +46,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] + credentials = @application.services.find_service(FILTER, APITOKEN, ENVIRONMENTID)['credentials'] environment_variables = @droplet.environment_variables manifest = agent_manifest From 2544c32cca91350b581a2e422b46281cab47548c Mon Sep 17 00:00:00 2001 From: Johannes Tuchscherer Date: Wed, 18 Oct 2017 15:40:42 +0200 Subject: [PATCH 367/812] Clarify Heap Dump Generation Requirements This change updates the JRE documentation to clarify the requirements to have heap dumps generated and written to disk. [resolves #501] --- docs/jre-open_jdk_jre.md | 2 +- docs/jre-oracle_jre.md | 2 +- docs/jre-zulu_jre.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index ac80460de3..7ec65b96b5 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -69,7 +69,7 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` +If a [Volume Service][] with the string `heap-dump` in its name or tag is bound to the application, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 360f6d67fa..3f4d376d53 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -85,7 +85,7 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` +If a [Volume Service][] with the string `heap-dump` in its name or tag is bound to the application, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index 5910281838..d8ba2df866 100755 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -76,7 +76,7 @@ Memory pool usage: PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 ``` -If a heap dump [Volume Service][] is bound, terminal heap dumps will be written with the pattern `/-/-/--.hprof` +If a [Volume Service][] with the string `heap-dump` in its name or tag is bound to the application, terminal heap dumps will be written with the pattern `/-/-/--.hprof` ```plain Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof From 5f62e2f9fe4c7518846a448d6a16fdb30152cf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madis=20P=C3=A4rn?= Date: Fri, 20 Oct 2017 11:50:02 +0300 Subject: [PATCH 368/812] Fixed JRebel documentation links --- docs/framework-jrebel_agent.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/framework-jrebel_agent.md b/docs/framework-jrebel_agent.md index c1c6a5f6c8..a8923c3058 100644 --- a/docs/framework-jrebel_agent.md +++ b/docs/framework-jrebel_agent.md @@ -5,7 +5,7 @@ The JRebel Agent Framework causes an application to be automatically configured - + @@ -29,9 +29,9 @@ The framework can be configured by modifying the [`config/jrebel_agent.yml`][] f [Configuration and Extension]: ../README.md#configuration-and-extension [`config/jrebel_agent.yml`]: ../config/jrebel_agent.yml -[JRebel Cloud/Remote]: http://manuals.zeroturnaround.com/jrebel/remoting/index.html +[JRebel Cloud/Remote]: http://manuals.zeroturnaround.com/jrebel/remoteserver/index.html [JRebel]: http://zeroturnaround.com/software/jrebel/ -[pivotal]: http://manuals.zeroturnaround.com/jrebel/remoting/pivotal.html +[pivotal]: http://manuals.zeroturnaround.com/jrebel/remoteserver/pivotal.html [repositories]: extending-repositories.md [this listing]: http://dl.zeroturnaround.com/jrebel/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering From 7b1763bff17bcaa46bf8b352c8894e5efe4eb485 Mon Sep 17 00:00:00 2001 From: Madis Parn Date: Fri, 20 Oct 2017 12:39:16 +0300 Subject: [PATCH 369/812] Added support from detecting rebel-remote.xml with spring-boot --- lib/java_buildpack/framework/jrebel_agent.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index 27816b2efb..0cb0341251 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -49,6 +49,7 @@ def supports? enabled? && ( jrebel_configured?(@application.root) || jrebel_configured?(@application.root + 'WEB-INF/classes') || + jrebel_configured?(@application.root + 'BOOT-INF/classes') || jars_with_jrebel_configured?(@application.root)) end From 087010f9eb653a06224fc342c5bc9ce09e61e22f Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 23 Oct 2017 15:17:20 -0700 Subject: [PATCH 370/812] Disable JVM DNS Caching Previously JVM DNS caching was always governed by the JVM's settings of always/10s. This causes issues in situations where DNS entries are being refreshed by BOSH quite quickly. To address this, BOSH has added a DNS server of its own that is accessible on a link-local address. This BOSH DNS server implements the appropriate caching close by (and obeying ttls) removing the need for the JVM to so. This change notices the BOSH DNS as staging time and if it exists, disables the default JVM DNS caching in lieu of the BOSH DNS caching. [resolves #505] --- .idea/dictionaries/bhale.xml | 1 + .rubocop.yml | 4 +- config/components.yml | 2 +- lib/java_buildpack/buildpack.rb | 4 +- lib/java_buildpack/component/droplet.rb | 8 ++- lib/java_buildpack/component/networking.rb | 54 +++++++++++++++++++ .../component/security_providers.rb | 2 +- ...security_providers.rb => java_security.rb} | 5 +- lib/java_buildpack/jre/open_jdk_like_jre.rb | 22 ++++++++ spec/droplet_helper.rb | 6 ++- .../framework_java_security_networking | 4 ++ ...framework_java_security_security_providers | 2 + ...roviders_spec.rb => java_security_spec.rb} | 24 ++++++--- .../jre/open_jdk_like_jre_spec.rb | 23 ++++++++ 14 files changed, 146 insertions(+), 15 deletions(-) create mode 100644 lib/java_buildpack/component/networking.rb rename lib/java_buildpack/framework/{security_providers.rb => java_security.rb} (91%) create mode 100644 spec/fixtures/framework_java_security_networking create mode 100644 spec/fixtures/framework_java_security_security_providers rename spec/java_buildpack/framework/{security_providers_spec.rb => java_security_spec.rb} (58%) diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 42f7cc42eb..bf6ad475e0 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -65,6 +65,7 @@ myhost mypass myuser + networkaddress newrelic newrelicagent overweaving diff --git a/.rubocop.yml b/.rubocop.yml index 236b840043..e9846b9ead 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -31,9 +31,9 @@ Metrics/CyclomaticComplexity: Metrics/LineLength: Max: 120 Metrics/MethodLength: - Max: 20 + Max: 25 Metrics/ParameterLists: - Max: 8 + Max: 10 Metrics/PerceivedComplexity: Max: 10 RSpec/ExampleLength: diff --git a/config/components.yml b/config/components.yml index ec8c8ff1f0..13e389518b 100644 --- a/config/components.yml +++ b/config/components.yml @@ -66,5 +66,5 @@ frameworks: - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::YourKitProfiler" - "JavaBuildpack::Framework::TakipiAgent" - - "JavaBuildpack::Framework::SecurityProviders" + - "JavaBuildpack::Framework::JavaSecurity" - "JavaBuildpack::Framework::JavaOpts" diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index e7083fa7c0..0a19c140d5 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -23,6 +23,7 @@ require 'java_buildpack/component/immutable_java_home' require 'java_buildpack/component/java_opts' require 'java_buildpack/component/mutable_java_home' +require 'java_buildpack/component/networking' require 'java_buildpack/component/security_providers' require 'java_buildpack/logging/logger_factory' require 'java_buildpack/util/cache/application_cache' @@ -131,6 +132,7 @@ def initialize(app_dir, application) 'env_vars' => Component::EnvironmentVariables.new(app_dir), 'extension_directories' => Component::ExtensionDirectories.new(app_dir), 'java_opts' => @java_opts, + 'networking' => Component::Networking.new, 'security_providers' => Component::SecurityProviders.new } @@ -181,7 +183,7 @@ def instantiate(components, java_home, component_info) droplet: Component::Droplet.new(component_info['additional_libraries'], component_id, component_info['env_vars'], component_info['extension_directories'], java_home, component_info['java_opts'], component_info['app_dir'], - component_info['security_providers']) + component_info['networking'], component_info['security_providers']) } component.constantize.new(context) end diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index 4f602a8434..db8f90a4b3 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -56,6 +56,10 @@ class Droplet # @return [JavaOpts] the shared +JavaOpts+ instance for all components attr_reader :java_opts + # @!attribute [r] networking + # @return [Networking] the shared +Networking+ instance for all components + attr_reader :networking + # @!attribute [r] root # @return [JavaBuildpack::Util::FilteringPathname] the root of the droplet's fileystem filtered so that it # excludes files in the sandboxes of other components @@ -83,10 +87,11 @@ class Droplet # be an instance of +MutableJavaHome+. Otherwise it should # be an instance of +ImmutableJavaHome+. # @param [JavaOpts] java_opts the shared +JavaOpts+ instance for all components + # @param [Networking] networking the shared +Networking+ instance for all components # @param [Pathname] root the root of the droplet # @param [SecurityProviders] security_providers the shared +SecurityProviders+ instance for all components def initialize(additional_libraries, component_id, env_vars, extension_directories, java_home, java_opts, root, - security_providers) + networking, security_providers) @additional_libraries = additional_libraries @component_id = component_id @@ -110,6 +115,7 @@ def initialize(additional_libraries, component_id, env_vars, extension_directori ->(path) { !in?(path, buildpack_root) || in?(path, @sandbox) }, true ) + @networking = networking @security_providers = security_providers end diff --git a/lib/java_buildpack/component/networking.rb b/lib/java_buildpack/component/networking.rb new file mode 100644 index 0000000000..7809ba3345 --- /dev/null +++ b/lib/java_buildpack/component/networking.rb @@ -0,0 +1,54 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component' + +module JavaBuildpack + module Component + + # An abstraction around the networking configuration provided to a droplet by components. + # + # A new instance of this type should be created once for the application. + class Networking + + # @!attribute [rw] networkaddress_cache_ttl + # @return [Integer] the number of seconds to cache the successful lookup + attr_accessor :networkaddress_cache_ttl + + # @!attribute [rw] networkaddress_cache_negative_ttl + # @return [Integer] the number of seconds to cache the failure for un-successful lookups + attr_accessor :networkaddress_cache_negative_ttl + + # Write the networking configuration to a destination file + # + # @param [Pathname] destination the destination to write to + # @return [Void] + def write_to(destination) + FileUtils.mkdir_p destination.parent + + destination.open(File::CREAT | File::APPEND | File::WRONLY) do |f| + f.write "networkaddress.cache.ttl=#{@networkaddress_cache_ttl}\n" if @networkaddress_cache_ttl + + if @networkaddress_cache_negative_ttl + f.write "networkaddress.cache.negative.ttl=#{networkaddress_cache_negative_ttl}\n" + end + end + end + + end + + end +end diff --git a/lib/java_buildpack/component/security_providers.rb b/lib/java_buildpack/component/security_providers.rb index df7f26fcdd..097f118ccf 100644 --- a/lib/java_buildpack/component/security_providers.rb +++ b/lib/java_buildpack/component/security_providers.rb @@ -31,7 +31,7 @@ class SecurityProviders < Array def write_to(destination) FileUtils.mkdir_p destination.parent - destination.open(File::CREAT | File::WRONLY) do |f| + destination.open(File::CREAT | File::APPEND | File::WRONLY) do |f| each_with_index { |security_provider, index| f.write "security.provider.#{index + 1}=#{security_provider}\n" } end end diff --git a/lib/java_buildpack/framework/security_providers.rb b/lib/java_buildpack/framework/java_security.rb similarity index 91% rename from lib/java_buildpack/framework/security_providers.rb rename to lib/java_buildpack/framework/java_security.rb index 12a4e1b7ef..89e4d5b2e3 100644 --- a/lib/java_buildpack/framework/security_providers.rb +++ b/lib/java_buildpack/framework/java_security.rb @@ -21,15 +21,16 @@ module JavaBuildpack module Framework # Encapsulates the functionality for contributing custom Security Providers to an application. - class SecurityProviders < JavaBuildpack::Component::BaseComponent + class JavaSecurity < JavaBuildpack::Component::BaseComponent # (see JavaBuildpack::Component::BaseComponent#detect) def detect - SecurityProviders.to_s.dash_case + JavaSecurity.to_s.dash_case end # (see JavaBuildpack::Component::BaseComponent#compile) def compile + @droplet.networking.write_to java_security @droplet.security_providers.write_to java_security end diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index 424687050b..839db2865d 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -13,10 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +require 'ipaddr' require 'fileutils' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/jre' require 'java_buildpack/util/tokenized_version' +require 'resolv' module JavaBuildpack module Jre @@ -48,6 +50,7 @@ def detect def compile download_tar @droplet.copy_resources + disable_dns_caching if link_local_dns? return if @droplet.java_home.java_8_or_later? @@ -62,6 +65,25 @@ def release .add_system_property('java.io.tmpdir', '$TMPDIR') end + private + + LINK_LOCAL = IPAddr.new('169.254.0.0/16').freeze + + private_constant :LINK_LOCAL + + def disable_dns_caching + puts ' JVM DNS caching disabled in lieu of BOSH DNS caching' + + @droplet.networking.networkaddress_cache_ttl = 0 + @droplet.networking.networkaddress_cache_negative_ttl = 0 + end + + def link_local_dns? + Resolv::DNS::Config.new.lazy_initialize.nameserver_port.any? do |nameserver_port| + LINK_LOCAL.include? IPAddr.new(nameserver_port[0]) + end + end + end end diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index 18490ee3ea..f85e860910 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -22,6 +22,7 @@ require 'java_buildpack/component/extension_directories' require 'java_buildpack/component/immutable_java_home' require 'java_buildpack/component/java_opts' +require 'java_buildpack/component/networking' require 'java_buildpack/component/security_providers' require 'java_buildpack/util/snake_case' require 'pathname' @@ -38,7 +39,8 @@ let(:droplet) do JavaBuildpack::Component::Droplet.new(additional_libraries, component_id, environment_variables, - extension_directories, java_home, java_opts, app_dir, security_providers) + extension_directories, java_home, java_opts, app_dir, networking, + security_providers) end let(:extension_directories) { JavaBuildpack::Component::ExtensionDirectories.new app_dir } @@ -62,6 +64,8 @@ java_opts end + let(:networking) { JavaBuildpack::Component::Networking.new } + let(:security_providers) { JavaBuildpack::Component::SecurityProviders.new } before do diff --git a/spec/fixtures/framework_java_security_networking b/spec/fixtures/framework_java_security_networking new file mode 100644 index 0000000000..60738b2246 --- /dev/null +++ b/spec/fixtures/framework_java_security_networking @@ -0,0 +1,4 @@ +networkaddress.cache.ttl=-1 +networkaddress.cache.negative.ttl=-2 +security.provider.1=test-security-provider-1 +security.provider.2=test-security-provider-2 diff --git a/spec/fixtures/framework_java_security_security_providers b/spec/fixtures/framework_java_security_security_providers new file mode 100644 index 0000000000..b4e7d7fc84 --- /dev/null +++ b/spec/fixtures/framework_java_security_security_providers @@ -0,0 +1,2 @@ +security.provider.1=test-security-provider-1 +security.provider.2=test-security-provider-2 diff --git a/spec/java_buildpack/framework/security_providers_spec.rb b/spec/java_buildpack/framework/java_security_spec.rb similarity index 58% rename from spec/java_buildpack/framework/security_providers_spec.rb rename to spec/java_buildpack/framework/java_security_spec.rb index aaac041450..050298461e 100644 --- a/spec/java_buildpack/framework/security_providers_spec.rb +++ b/spec/java_buildpack/framework/java_security_spec.rb @@ -16,28 +16,40 @@ require 'spec_helper' require 'component_helper' require 'fileutils' -require 'java_buildpack/framework/security_providers' +require 'java_buildpack/framework/java_security' -describe JavaBuildpack::Framework::SecurityProviders do +describe JavaBuildpack::Framework::JavaSecurity do include_context 'component_helper' it 'adds extension directories to system properties' do component.release - expect(java_opts).to include('-Djava.ext.dirs=$PWD/.java-buildpack/security_providers/test-extension-directory-1:' \ - '$PWD/.java-buildpack/security_providers/test-extension-directory-2') + expect(java_opts).to include('-Djava.ext.dirs=$PWD/.java-buildpack/java_security/test-extension-directory-1:' \ + '$PWD/.java-buildpack/java_security/test-extension-directory-2') end - it 'writes new security properties' do + it 'writes security provider security properties' do component.compile expect(sandbox + 'java.security').to exist + expect(File.read(sandbox + 'java.security')) + .to eq File.read('spec/fixtures/framework_java_security_security_providers') + end + + it 'writes networking security properties' do + networking.networkaddress_cache_ttl = -1 + networking.networkaddress_cache_negative_ttl = -2 + + component.compile + + expect(sandbox + 'java.security').to exist + expect(File.read(sandbox + 'java.security')).to eq File.read('spec/fixtures/framework_java_security_networking') end it 'adds security properties to system properties' do component.release - expect(java_opts).to include('-Djava.security.properties=$PWD/.java-buildpack/security_providers/' \ + expect(java_opts).to include('-Djava.security.properties=$PWD/.java-buildpack/java_security/' \ 'java.security') end diff --git a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index 3504ac04c7..dba74a01d8 100644 --- a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -17,6 +17,7 @@ require 'component_helper' require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/jre/open_jdk_like_jre' +require 'resolv' describe JavaBuildpack::Jre::OpenJDKLikeJre do include_context 'component_helper' @@ -49,4 +50,26 @@ expect(java_opts).to include('-Djava.io.tmpdir=$TMPDIR') end + it 'does not disable dns caching if no BOSH DNS', + cache_fixture: 'stub-java.tar.gz' do + + component.detect + component.compile + + expect(networking.networkaddress_cache_ttl).not_to be + expect(networking.networkaddress_cache_negative_ttl).not_to be + end + + it 'disables dns caching if BOSH DNS', + cache_fixture: 'stub-java.tar.gz' do + + allow_any_instance_of(Resolv::DNS::Config).to receive(:nameserver_port).and_return([['169.254.0.2', 53]]) + + component.detect + component.compile + + expect(networking.networkaddress_cache_ttl).to eq 0 + expect(networking.networkaddress_cache_negative_ttl).to eq 0 + end + end From 67b5da51783264946ab5dd65c26bd0fab59b2e37 Mon Sep 17 00:00:00 2001 From: Jammy Louie Date: Mon, 30 Oct 2017 15:38:45 -0400 Subject: [PATCH 371/812] Update Geode Repository Root Previously, the Geode artifacts were hosted in a Cloud Foundry Foundation repository. As it turns out that some of the binaries were based on non-open source code, this wasn't tenable. This change updates the repository root to point to a repository hosted by Pivotal. [resolves #509][#152411660] --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index 65d18a576e..ea627d4188 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -41,4 +41,4 @@ redis_store: connection_pool_size: 2 geode_store: version: 0.+ - repository_root: "{default.repository.root}/geode-store" + repository_root: "https://repo.spring.io/ext-release-local/geode-store" From f0c478c759fb1cdda5f4d50cf57dc53e49e280c1 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 30 Oct 2017 15:50:50 -0700 Subject: [PATCH 372/812] Large Output Shell Stall Previously if a large amount of output was received during a shell call, the buildpack would stall because the process' output buffer would fill to capacity before the process would complete. This change assigns the output to a variable during execution, ensuring that the process' output buffers do not fill during execution. [resolves #507] --- lib/java_buildpack/util/shell.rb | 7 +++++-- spec/java_buildpack/util/shell_spec.rb | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/util/shell.rb b/lib/java_buildpack/util/shell.rb index 326f5c8fc3..08b8db693c 100644 --- a/lib/java_buildpack/util/shell.rb +++ b/lib/java_buildpack/util/shell.rb @@ -28,10 +28,13 @@ module Shell # @return [Void] def shell(*args) Open3.popen3(*args) do |_stdin, stdout, stderr, wait_thr| + out = stdout.gets nil + err = stderr.gets nil + unless wait_thr.value.success? puts "\nCommand '#{args.join ' '}' has failed" - puts "STDOUT: #{stdout.gets nil}" - puts "STDERR: #{stderr.gets nil}" + puts "STDOUT: #{out}" + puts "STDERR: #{err}" raise end diff --git a/spec/java_buildpack/util/shell_spec.rb b/spec/java_buildpack/util/shell_spec.rb index f34b6067c4..5316544c07 100644 --- a/spec/java_buildpack/util/shell_spec.rb +++ b/spec/java_buildpack/util/shell_spec.rb @@ -16,6 +16,7 @@ require 'spec_helper' require 'console_helper' require 'java_buildpack/util/shell' +require 'timeout' describe JavaBuildpack::Util::Shell do include described_class @@ -29,4 +30,8 @@ expect { shell 'false' }.to raise_error end + it 'handles a large amount of output' do + Timeout.timeout(2) { shell "cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 1000000 | head -n 1" } + end + end From a0c88fb73a4e417cef37a15449fb4e7908edf326 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 8 Nov 2017 09:37:14 -0800 Subject: [PATCH 373/812] Auto-Reconfiguration 2.0 This change updates auto-reconfiguration to 2.+. This change enables auto- reconfiguration of Spring Boot 2 applications, and vastly simplifies how auto- reconfiguration is performed. This change also removes support for auto- reconfiguring Play applications. [resolves #485] --- .idea/.rakeTasks | 2 +- README.md | 2 - config/components.yml | 2 - .../play_framework_auto_reconfiguration.yml | 22 ------ config/play_framework_jpa_plugin.yml | 20 ----- config/spring_auto_reconfiguration.yml | 2 +- ...ork-play_framework_auto_reconfiguration.md | 32 -------- docs/framework-play_framework_jpa_plugin.md | 36 --------- .../play_framework_auto_reconfiguration.rb | 49 ------------ .../framework/play_framework_jpa_plugin.rb | 65 ---------------- ...lay_framework_auto_reconfiguration_spec.rb | 65 ---------------- .../play_framework_jpa_plugin_spec.rb | 77 ------------------- 12 files changed, 2 insertions(+), 372 deletions(-) delete mode 100644 config/play_framework_auto_reconfiguration.yml delete mode 100644 config/play_framework_jpa_plugin.yml delete mode 100644 docs/framework-play_framework_auto_reconfiguration.md delete mode 100644 docs/framework-play_framework_jpa_plugin.md delete mode 100644 lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb delete mode 100644 lib/java_buildpack/framework/play_framework_jpa_plugin.rb delete mode 100644 spec/java_buildpack/framework/play_framework_auto_reconfiguration_spec.rb delete mode 100644 spec/java_buildpack/framework/play_framework_jpa_plugin_spec.rb diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index 368e4e50f6..23d30fbda3 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/README.md b/README.md index 7e574a63ee..5ea338524f 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,6 @@ The buildpack supports extension through the use of Git repository forking. The * [Multiple Buildpack](docs/framework-multi_buildpack.md) * [Metric Writer](docs/framework-metric_writer.md) ([Configuration](docs/framework-metric_writer.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) - * [Play Framework Auto Reconfiguration](docs/framework-play_framework_auto_reconfiguration.md) ([Configuration](docs/framework-play_framework_auto_reconfiguration.md#configuration)) - * [Play Framework JPA Plugin](docs/framework-play_framework_jpa_plugin.md) ([Configuration](docs/framework-play_framework_jpa_plugin.md#configuration)) * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 13e389518b..c99814291b 100644 --- a/config/components.yml +++ b/config/components.yml @@ -58,8 +58,6 @@ frameworks: - "JavaBuildpack::Framework::MariaDbJDBC" - "JavaBuildpack::Framework::MetricWriter" - "JavaBuildpack::Framework::NewRelicAgent" - - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration" - - "JavaBuildpack::Framework::PlayFrameworkJPAPlugin" - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::ProtectAppSecurityProvider" - "JavaBuildpack::Framework::SpringAutoReconfiguration" diff --git a/config/play_framework_auto_reconfiguration.yml b/config/play_framework_auto_reconfiguration.yml deleted file mode 100644 index 1b91ed1ab8..0000000000 --- a/config/play_framework_auto_reconfiguration.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Configuration for the Play Auto Reconfiguration framework. -# Note that the repository is shared with the Spring Auto Reconfiguration framework and should be kept in step to -# avoid conflicts. ---- -version: 1.+ -repository_root: "{default.repository.root}/auto-reconfiguration" -enabled: true diff --git a/config/play_framework_jpa_plugin.yml b/config/play_framework_jpa_plugin.yml deleted file mode 100644 index a53d4a4bc9..0000000000 --- a/config/play_framework_jpa_plugin.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Configuration for the Play JPA Plugin framework ---- -version: 1.+ -repository_root: "{default.repository.root}/play-jpa-plugin" -enabled: true diff --git a/config/spring_auto_reconfiguration.yml b/config/spring_auto_reconfiguration.yml index e8f1f592ac..baebf8f72c 100644 --- a/config/spring_auto_reconfiguration.yml +++ b/config/spring_auto_reconfiguration.yml @@ -17,6 +17,6 @@ # Note that the repository is shared with the Play Auto Reconfiguration framework and should be kept in step to # avoid conflicts. --- -version: 1.+ +version: 2.+ repository_root: "{default.repository.root}/auto-reconfiguration" enabled: true diff --git a/docs/framework-play_framework_auto_reconfiguration.md b/docs/framework-play_framework_auto_reconfiguration.md deleted file mode 100644 index 04efd16d9a..0000000000 --- a/docs/framework-play_framework_auto_reconfiguration.md +++ /dev/null @@ -1,32 +0,0 @@ -# Play Framework Auto-reconfiguration Framework -The Play Framework Auto-reconfiguration Framework causes an application to be automatically reconfigured to work with configured cloud services. - -
Detection CriterionExistence of a rebel-remote.xml file inside the application archive. This file is present in every application that is configured to use JRebel Cloud/Remote.Existence of a rebel-remote.xml file inside the application archive. This file is present in every application that is configured to use JRebel Cloud/Remote.
Tags
- - - - - - - - -
Detection CriterionAn application is a Play Framework application
Tagsplay-framework-auto-reconfiguration=<version>
-Tags are printed to standard output by the buildpack detect script - -## Configuration -For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. - -The framework can be configured by modifying the [`config/play_framework_auto_reconfiguration.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. - - -| Name | Description -| ---- | ----------- -| `enabled` | Whether to attempt auto-reconfiguration -| `repository_root` | The URL of the Auto-reconfiguration repository index ([details][repositories]). -| `version` | The version of Auto-reconfiguration to use. Candidate versions can be found in [this listing][]. - -[Configuration and Extension]: ../README.md#configuration-and-extension -[`config/play_framework_auto_reconfiguration.yml`]: ../config/config/play_framework_auto_reconfiguration.yml -[repositories]: extending-repositories.md -[this listing]: http://download.pivotal.io.s3.amazonaws.com/auto-reconfiguration/index.yml -[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/framework-play_framework_jpa_plugin.md b/docs/framework-play_framework_jpa_plugin.md deleted file mode 100644 index ed7b0de4bb..0000000000 --- a/docs/framework-play_framework_jpa_plugin.md +++ /dev/null @@ -1,36 +0,0 @@ -# Play Framework JPA Plugin Framework -The Play Framework JPA Plugin Framework causes an application to be automatically reconfigured to work with configured cloud services. - - - - - - - - - - -
Detection Criterion -
    -
  • An application is a Play Framework 2.0 application
  • -
  • An application uses the play-java-jpa plugin
  • -
-
Tagsplay-framework-jpa-plugin=<version>
-Tags are printed to standard output by the buildpack detect script - -## Configuration -For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. - -The framework can be configured by modifying the [`config/play_framework_jpa_plugin.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. - -| Name | Description -| ---- | ----------- -| `enabled` | Whether to attempt reconfiguration -| `repository_root` | The URL of the Play Framework JPA Plugin repository index ([details][repositories]). -| `version` | The version of the Play Framework JPA Plugin to use. Candidate versions can be found in [this listing][]. - -[Configuration and Extension]: ../README.md#configuration-and-extension -[`config/play_framework_jpa_plugin.yml`]: ../config/play_framework_jpa_plugin.yml -[repositories]: extending-repositories.md -[this listing]: http://download.pivotal.io.s3.amazonaws.com/play-jpa-plugin/index.yml -[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb b/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb deleted file mode 100644 index 6437d54d69..0000000000 --- a/lib/java_buildpack/framework/play_framework_auto_reconfiguration.rb +++ /dev/null @@ -1,49 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/framework' -require 'java_buildpack/util/play/factory' - -module JavaBuildpack - module Framework - - # Encapsulates the functionality for enabling cloud auto-reconfiguration in Play applications. Note that Spring - # auto- reconfiguration is covered by the SpringAutoReconfiguration framework. The reconfiguration performed here is - # to override Play application configuration to bind a Play application to cloud resources. - class PlayFrameworkAutoReconfiguration < JavaBuildpack::Component::VersionedDependencyComponent - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar - @droplet.additional_libraries << (@droplet.sandbox + jar_name) - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release - @droplet.additional_libraries << (@droplet.sandbox + jar_name) - end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - @configuration['enabled'] && JavaBuildpack::Util::Play::Factory.create(@droplet) - end - - end - - end -end diff --git a/lib/java_buildpack/framework/play_framework_jpa_plugin.rb b/lib/java_buildpack/framework/play_framework_jpa_plugin.rb deleted file mode 100644 index 0da10eee5a..0000000000 --- a/lib/java_buildpack/framework/play_framework_jpa_plugin.rb +++ /dev/null @@ -1,65 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/framework' -require 'java_buildpack/util/play/factory' - -module JavaBuildpack - module Framework - - # Encapsulates the detect, compile, and release functionality for enabling cloud auto-reconfiguration in Play - # applications that use JPA. Note that Spring auto-reconfiguration is covered by the SpringAutoReconfiguration - # framework. The reconfiguration performed here is to override Play application configuration to bind a Play - # application to cloud resources. - class PlayFrameworkJPAPlugin < JavaBuildpack::Component::VersionedDependencyComponent - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_jar - @droplet.additional_libraries << (@droplet.sandbox + jar_name) - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release - @droplet.additional_libraries << (@droplet.sandbox + jar_name) - end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - candidate = false - - play_app = JavaBuildpack::Util::Play::Factory.create @droplet - candidate = uses_jpa?(play_app) || play20?(play_app.version) if play_app - - @configuration['enabled'] && candidate - end - - private - - def play20?(version) - version.start_with? '2.0' - end - - def uses_jpa?(play_app) - play_app.jar?(/.*play-java-jpa.*\.jar/) - end - - end - - end -end diff --git a/spec/java_buildpack/framework/play_framework_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/play_framework_auto_reconfiguration_spec.rb deleted file mode 100644 index df665e6959..0000000000 --- a/spec/java_buildpack/framework/play_framework_auto_reconfiguration_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/framework/play_framework_auto_reconfiguration' - -describe JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration do - include_context 'component_helper' - - let(:configuration) { { 'enabled' => true } } - - it 'detects with application configuration', - app_fixture: 'container_play_2.1_dist' do - - expect(component.detect).to eq("play-framework-auto-reconfiguration=#{version}") - end - - it 'does not detect without application configuration', - app_fixture: 'container_play_too_deep' do - - expect(component.detect).to be_nil - end - - context do - let(:configuration) { { 'enabled' => false } } - - it 'does not detect if disabled', - app_fixture: 'container_play_2.1_dist' do - - expect(component.detect).to be_nil - end - end - - it 'downloads additional libraries', - app_fixture: 'container_play_2.1_dist', - cache_fixture: 'stub-auto-reconfiguration.jar' do - - component.compile - - expect(sandbox + "play_framework_auto_reconfiguration-#{version}.jar").to exist - end - - it 'adds to the additional libraries', - app_fixture: 'container_play_2.1_dist', - cache_fixture: 'stub-auto-reconfiguration.jar' do - - component.release - - expect(additional_libraries).to include(sandbox + "play_framework_auto_reconfiguration-#{version}.jar") - end - -end diff --git a/spec/java_buildpack/framework/play_framework_jpa_plugin_spec.rb b/spec/java_buildpack/framework/play_framework_jpa_plugin_spec.rb deleted file mode 100644 index 45e16d41e2..0000000000 --- a/spec/java_buildpack/framework/play_framework_jpa_plugin_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/framework/play_framework_jpa_plugin' - -describe JavaBuildpack::Framework::PlayFrameworkJPAPlugin do - include_context 'component_helper' - - let(:configuration) { { 'enabled' => true } } - - it 'detects Play 2.0 application', - app_fixture: 'framework_play_jpa_plugin_play20' do - - expect(component.detect).to eq("play-framework-jpa-plugin=#{version}") - end - - context do - let(:configuration) { { 'enabled' => false } } - - it 'does not detect if disabled', - app_fixture: 'framework_play_jpa_plugin_play20' do - - expect(component.detect).to be_nil - end - end - - it 'detects staged application', - app_fixture: 'framework_play_jpa_plugin_staged' do - - expect(component.detect).to eq("play-framework-jpa-plugin=#{version}") - end - - it 'detects dist application', - app_fixture: 'framework_play_jpa_plugin_dist' do - - expect(component.detect).to eq("play-framework-jpa-plugin=#{version}") - end - - it 'does not detect non-JPA application', - app_fixture: 'container_play_2.1_dist' do - - expect(component.detect).to be_nil - end - - it 'downloads additional libraries', - app_fixture: 'framework_play_jpa_plugin_dist', - cache_fixture: 'stub-play-jpa-plugin.jar' do - - component.compile - - expect(sandbox + "play_framework_jpa_plugin-#{version}.jar").to exist - end - - it 'adds to additional libraries', - app_fixture: 'framework_play_jpa_plugin_dist', - cache_fixture: 'stub-play-jpa-plugin.jar' do - - component.release - - expect(additional_libraries).to include(sandbox + "play_framework_jpa_plugin-#{version}.jar") - end - -end From 4012798ed34b6f939c621077105634010c480d4a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 8 Nov 2017 09:42:18 -0800 Subject: [PATCH 374/812] Polishing --- rakelib/versions_task.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index cea7973d18..0cd68d0845 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -74,8 +74,6 @@ def initialize 'memory_calculator' => 'Memory Calculator', 'metric_writer' => 'Metric Writer', 'new_relic_agent' => 'New Relic Agent', - 'play_framework_auto_reconfiguration' => 'Play Framework Auto-reconfiguration', - 'play_framework_jpa_plugin' => 'Play Framework JPA Plugin', 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', 'redis_store' => 'Redis Session Store', From 9f81617114e11381f0d96ba9243c567fe6aac7df Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 8 Nov 2017 10:28:39 -0800 Subject: [PATCH 375/812] Update Servlet 2 Configuration This change updates the Servlet 2 configuration to use the new classes and packages for auto-reconfiguration. --- docs/framework-spring_auto_reconfiguration.md | 2 +- .../spring_auto_reconfiguration/web_xml_modifier.rb | 12 ++++++------ spec/fixtures/web_root_existing_params_after.xml | 2 +- spec/fixtures/web_root_no_params_after.xml | 2 +- .../web_servlet_existing_load_on_startup_after.xml | 2 +- spec/fixtures/web_servlet_existing_params_after.xml | 2 +- spec/fixtures/web_servlet_load_on_startup_after.xml | 2 +- spec/fixtures/web_servlet_no_params_after.xml | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/framework-spring_auto_reconfiguration.md b/docs/framework-spring_auto_reconfiguration.md index bd737a8503..749e7f677e 100644 --- a/docs/framework-spring_auto_reconfiguration.md +++ b/docs/framework-spring_auto_reconfiguration.md @@ -13,7 +13,7 @@ The Spring Auto-reconfiguration Framework causes an application to be automatica Tags are printed to standard output by the buildpack detect script -If a `/WEB-INF/web.xml` file exists, the framework will modify it in addition to making the auto-reconfiguration JAR available on the classpath. This modification consists of adding `org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer`, `org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer`, and `org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer` to the collection of `contextInitializerClasses`. The Spring Auto-reconfiguration Framework also adds the `cloud` profile to any existing Spring profiles such as those defined in the [`SPRING_PROFILES_ACTIVE`][] environment variable. +If a `/WEB-INF/web.xml` file exists, the framework will modify it in addition to making the auto-reconfiguration JAR available on the classpath. This modification consists of adding `org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer`, `org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer`, and `org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer` to the collection of `contextInitializerClasses`. The Spring Auto-reconfiguration Framework also adds the `cloud` profile to any existing Spring profiles such as those defined in the [`SPRING_PROFILES_ACTIVE`][] environment variable. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb index 7fd9928a2c..0415c1ad04 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb @@ -23,9 +23,9 @@ module Framework # A class that encapsulates the modification of a +web.xml+ Servlet configuration file for the Auto-reconfiguration # framework. The modifications of +web.xml+ consist of augmenting +contextInitializerClasses+. The function starts # by enumerating the current +contextInitializerClasses+. If none exist, a default configuration is created with no - # value as the default. The +org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer+, - # +org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer+, and - # +org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer+ classes are then + # value as the default. The +org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer+, + # +org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer+, and + # +org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer+ classes are then # added to the collection of classes. class WebXmlModifier @@ -66,9 +66,9 @@ def to_s private CONTEXT_INITIALIZER_ADDITIONAL = %w[ - org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer - org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer - org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer + org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer + org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer ].freeze CONTEXT_INITIALIZER_CLASSES = 'contextInitializerClasses'.freeze diff --git a/spec/fixtures/web_root_existing_params_after.xml b/spec/fixtures/web_root_existing_params_after.xml index cff6301db6..70a94abba9 100644 --- a/spec/fixtures/web_root_existing_params_after.xml +++ b/spec/fixtures/web_root_existing_params_after.xml @@ -21,7 +21,7 @@ contextInitializerClasses - com.gopivotal.test,org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + com.gopivotal.test,org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer diff --git a/spec/fixtures/web_root_no_params_after.xml b/spec/fixtures/web_root_no_params_after.xml index 89ae5fb6f3..a348f28cda 100644 --- a/spec/fixtures/web_root_no_params_after.xml +++ b/spec/fixtures/web_root_no_params_after.xml @@ -21,7 +21,7 @@ contextInitializerClasses - org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer diff --git a/spec/fixtures/web_servlet_existing_load_on_startup_after.xml b/spec/fixtures/web_servlet_existing_load_on_startup_after.xml index 0328ab3033..b6383f5721 100644 --- a/spec/fixtures/web_servlet_existing_load_on_startup_after.xml +++ b/spec/fixtures/web_servlet_existing_load_on_startup_after.xml @@ -21,7 +21,7 @@ contextInitializerClasses - com.gopivotal.test,org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + com.gopivotal.test,org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer 1 diff --git a/spec/fixtures/web_servlet_existing_params_after.xml b/spec/fixtures/web_servlet_existing_params_after.xml index 50e1356ee7..0185749bcc 100644 --- a/spec/fixtures/web_servlet_existing_params_after.xml +++ b/spec/fixtures/web_servlet_existing_params_after.xml @@ -21,7 +21,7 @@ contextInitializerClasses - com.gopivotal.test,org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + com.gopivotal.test,org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer diff --git a/spec/fixtures/web_servlet_load_on_startup_after.xml b/spec/fixtures/web_servlet_load_on_startup_after.xml index 6a6040938e..cf7ab6494f 100644 --- a/spec/fixtures/web_servlet_load_on_startup_after.xml +++ b/spec/fixtures/web_servlet_load_on_startup_after.xml @@ -21,7 +21,7 @@ contextInitializerClasses - org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer 1 diff --git a/spec/fixtures/web_servlet_no_params_after.xml b/spec/fixtures/web_servlet_no_params_after.xml index 19d9c9d370..968fbf78ba 100644 --- a/spec/fixtures/web_servlet_no_params_after.xml +++ b/spec/fixtures/web_servlet_no_params_after.xml @@ -21,7 +21,7 @@ contextInitializerClasses - org.cloudfoundry.reconfiguration.spring.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.spring.CloudAutoReconfigurationApplicationContextInitializer + org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer From fe4d2ce0c398a1ffc7cb49ee84d155b02343a72a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 8 Nov 2017 12:13:33 -0800 Subject: [PATCH 376/812] Remove Servlet 2 Support --- docs/framework-spring_auto_reconfiguration.md | 2 +- .../framework/spring_auto_reconfiguration.rb | 25 ---- .../web_xml_modifier.rb | 133 ------------------ .../WEB-INF/lib/spring-core-3.2.3.RELEASE.jar | 0 .../WEB-INF/web.xml | 16 --- .../web_root_existing_params_after.xml | 27 ---- .../web_root_existing_params_before.xml | 35 ----- ...eb_root_no_contextLoaderListener_after.xml | 17 --- ...b_root_no_contextLoaderListener_before.xml | 20 --- spec/fixtures/web_root_no_params_after.xml | 27 ---- spec/fixtures/web_root_no_params_before.xml | 26 ---- ...servlet_existing_load_on_startup_after.xml | 29 ---- ...ervlet_existing_load_on_startup_before.xml | 32 ----- .../web_servlet_existing_params_after.xml | 28 ---- .../web_servlet_existing_params_before.xml | 33 ----- .../web_servlet_load_on_startup_after.xml | 29 ---- .../web_servlet_load_on_startup_before.xml | 24 ---- ...web_servlet_no_DispatcherServlet_after.xml | 22 --- ...eb_servlet_no_DispatcherServlet_before.xml | 25 ---- spec/fixtures/web_servlet_no_params_after.xml | 28 ---- .../fixtures/web_servlet_no_params_before.xml | 25 ---- .../web_xml_modifier_spec.rb | 52 ------- .../spring_auto_reconfiguration_spec.rb | 23 --- 23 files changed, 1 insertion(+), 677 deletions(-) delete mode 100644 lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb delete mode 100644 spec/fixtures/framework_auto_reconfiguration_servlet_2/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar delete mode 100644 spec/fixtures/framework_auto_reconfiguration_servlet_2/WEB-INF/web.xml delete mode 100644 spec/fixtures/web_root_existing_params_after.xml delete mode 100644 spec/fixtures/web_root_existing_params_before.xml delete mode 100644 spec/fixtures/web_root_no_contextLoaderListener_after.xml delete mode 100644 spec/fixtures/web_root_no_contextLoaderListener_before.xml delete mode 100644 spec/fixtures/web_root_no_params_after.xml delete mode 100644 spec/fixtures/web_root_no_params_before.xml delete mode 100644 spec/fixtures/web_servlet_existing_load_on_startup_after.xml delete mode 100644 spec/fixtures/web_servlet_existing_load_on_startup_before.xml delete mode 100644 spec/fixtures/web_servlet_existing_params_after.xml delete mode 100644 spec/fixtures/web_servlet_existing_params_before.xml delete mode 100644 spec/fixtures/web_servlet_load_on_startup_after.xml delete mode 100644 spec/fixtures/web_servlet_load_on_startup_before.xml delete mode 100644 spec/fixtures/web_servlet_no_DispatcherServlet_after.xml delete mode 100644 spec/fixtures/web_servlet_no_DispatcherServlet_before.xml delete mode 100644 spec/fixtures/web_servlet_no_params_after.xml delete mode 100644 spec/fixtures/web_servlet_no_params_before.xml delete mode 100644 spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb diff --git a/docs/framework-spring_auto_reconfiguration.md b/docs/framework-spring_auto_reconfiguration.md index 749e7f677e..d8e8fbce85 100644 --- a/docs/framework-spring_auto_reconfiguration.md +++ b/docs/framework-spring_auto_reconfiguration.md @@ -13,7 +13,7 @@ The Spring Auto-reconfiguration Framework causes an application to be automatica Tags are printed to standard output by the buildpack detect script -If a `/WEB-INF/web.xml` file exists, the framework will modify it in addition to making the auto-reconfiguration JAR available on the classpath. This modification consists of adding `org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer`, `org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer`, and `org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer` to the collection of `contextInitializerClasses`. The Spring Auto-reconfiguration Framework also adds the `cloud` profile to any existing Spring profiles such as those defined in the [`SPRING_PROFILES_ACTIVE`][] environment variable. +The Spring Auto-reconfiguration Framework adds the `cloud` profile to any existing Spring profiles such as those defined in the [`SPRING_PROFILES_ACTIVE`][] environment variable. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 164ab2bb7b..1c43bac27a 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -16,7 +16,6 @@ require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/logging/logger_factory' require 'java_buildpack/framework' -require 'java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier' module JavaBuildpack module Framework @@ -37,8 +36,6 @@ def initialize(context) def compile download_jar @droplet.additional_libraries << (@droplet.sandbox + jar_name) - - modify_web_xml end # (see JavaBuildpack::Component::BaseComponent#release) @@ -53,28 +50,6 @@ def supports? @configuration['enabled'] && (@droplet.root + '**/*spring-core*.jar').glob.any? end - private - - def modify_web_xml - web_xml = @droplet.root + 'WEB-INF/web.xml' - - return unless web_xml.exist? - - puts ' Modifying /WEB-INF/web.xml for Auto Reconfiguration' - @logger.debug { " Original web.xml: #{web_xml.read}" } - - modifier = web_xml.open { |file| WebXmlModifier.new(file) } - modifier.augment_root_context - modifier.augment_servlet_contexts - - web_xml.open('w') do |file| - file.write(modifier.to_s) - file.fsync - end - - @logger.debug { " Modified web.xml: #{web_xml.read}" } - end - end end diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb deleted file mode 100644 index 0415c1ad04..0000000000 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier.rb +++ /dev/null @@ -1,133 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'java_buildpack/framework' -require 'rexml/document' -require 'rexml/formatters/pretty' - -module JavaBuildpack - module Framework - - # A class that encapsulates the modification of a +web.xml+ Servlet configuration file for the Auto-reconfiguration - # framework. The modifications of +web.xml+ consist of augmenting +contextInitializerClasses+. The function starts - # by enumerating the current +contextInitializerClasses+. If none exist, a default configuration is created with no - # value as the default. The +org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer+, - # +org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer+, and - # +org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer+ classes are then - # added to the collection of classes. - class WebXmlModifier - - # Creates a new instance of the modifier. - # - # @param [REXML::Document, String, IO] source the content of the +web.xml+ file to modify - def initialize(source) - @document = REXML::Document.new(source) - end - - # Make modifications to the root context - # - # @return [Void] - def augment_root_context - augment web_app(@document), 'context-param' if context_loader_listener? - end - - # Make modifications to the the servlet contexts - # - # @return [Void] - def augment_servlet_contexts - servlets.each do |servlet| - augment servlet, 'init-param' - end - end - - # Returns a +String+ representation of the modified +web.xml+. - # - # @return [String] a +String+ representation of the modified +web.xml+. - def to_s - output = '' - formatter.write(@document, output) - output << "\n" - - output - end - - private - - CONTEXT_INITIALIZER_ADDITIONAL = %w[ - org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer - org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer - org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer - ].freeze - - CONTEXT_INITIALIZER_CLASSES = 'contextInitializerClasses'.freeze - - CONTEXT_LOADER_LISTENER = 'ContextLoaderListener'.freeze - - DISPATCHER_SERVLET = 'DispatcherServlet'.freeze - - private_constant :CONTEXT_INITIALIZER_CLASSES, :CONTEXT_LOADER_LISTENER, :DISPATCHER_SERVLET - - def augment(root, param_type) - classes_string = xpath(root, "#{param_type}[param-name[contains(text(), - '#{CONTEXT_INITIALIZER_CLASSES}')]]/param-value/text()").first - classes_string = create_param(root, param_type, CONTEXT_INITIALIZER_CLASSES, '') unless classes_string - - classes = classes_string.value.strip.split(/[,;\s]+/) - classes = classes.concat CONTEXT_INITIALIZER_ADDITIONAL - - classes_string.value = classes.join(',') - end - - def context_loader_listener? - xpath(@document, "/web-app/listener/listener-class[contains(text(), '#{CONTEXT_LOADER_LISTENER}')]").any? - end - - def create_param(root, param_type, name, value) - load_on_startup = xpath(root, 'load-on-startup') - if load_on_startup.any? - param = REXML::Element.new param_type - load_on_startup.first.previous_sibling = param - else - param = REXML::Element.new param_type, root - end - param_name = REXML::Element.new 'param-name', param - REXML::Text.new name, true, param_name - - param_value = REXML::Element.new 'param-value', param - REXML::Text.new value, true, param_value - end - - def formatter - formatter = REXML::Formatters::Pretty.new(4) - formatter.compact = true - formatter - end - - def servlets - xpath(@document, "/web-app/servlet[servlet-class[contains(text(), '#{DISPATCHER_SERVLET}')]]") - end - - def web_app(root) - xpath(root, '/web-app').first - end - - def xpath(root, path) - REXML::XPath.match(root, path) - end - - end - - end -end diff --git a/spec/fixtures/framework_auto_reconfiguration_servlet_2/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar b/spec/fixtures/framework_auto_reconfiguration_servlet_2/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spec/fixtures/framework_auto_reconfiguration_servlet_2/WEB-INF/web.xml b/spec/fixtures/framework_auto_reconfiguration_servlet_2/WEB-INF/web.xml deleted file mode 100644 index 03448c513d..0000000000 --- a/spec/fixtures/framework_auto_reconfiguration_servlet_2/WEB-INF/web.xml +++ /dev/null @@ -1,16 +0,0 @@ - - diff --git a/spec/fixtures/web_root_existing_params_after.xml b/spec/fixtures/web_root_existing_params_after.xml deleted file mode 100644 index 70a94abba9..0000000000 --- a/spec/fixtures/web_root_existing_params_after.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - org.springframework.web.context.ContextLoaderListener - - - contextInitializerClasses - - com.gopivotal.test,org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer - - - diff --git a/spec/fixtures/web_root_existing_params_before.xml b/spec/fixtures/web_root_existing_params_before.xml deleted file mode 100644 index a4498e83ab..0000000000 --- a/spec/fixtures/web_root_existing_params_before.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - org.springframework.web.context.ContextLoaderListener - - - - - - contextInitializerClasses - - - com.gopivotal.test - - - - diff --git a/spec/fixtures/web_root_no_contextLoaderListener_after.xml b/spec/fixtures/web_root_no_contextLoaderListener_after.xml deleted file mode 100644 index e0c6b38a53..0000000000 --- a/spec/fixtures/web_root_no_contextLoaderListener_after.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/spec/fixtures/web_root_no_contextLoaderListener_before.xml b/spec/fixtures/web_root_no_contextLoaderListener_before.xml deleted file mode 100644 index c65c4b5948..0000000000 --- a/spec/fixtures/web_root_no_contextLoaderListener_before.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/spec/fixtures/web_root_no_params_after.xml b/spec/fixtures/web_root_no_params_after.xml deleted file mode 100644 index a348f28cda..0000000000 --- a/spec/fixtures/web_root_no_params_after.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - org.springframework.web.context.ContextLoaderListener - - - contextInitializerClasses - - org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer - - - diff --git a/spec/fixtures/web_root_no_params_before.xml b/spec/fixtures/web_root_no_params_before.xml deleted file mode 100644 index 8e0235c165..0000000000 --- a/spec/fixtures/web_root_no_params_before.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - org.springframework.web.context.ContextLoaderListener - - - - diff --git a/spec/fixtures/web_servlet_existing_load_on_startup_after.xml b/spec/fixtures/web_servlet_existing_load_on_startup_after.xml deleted file mode 100644 index b6383f5721..0000000000 --- a/spec/fixtures/web_servlet_existing_load_on_startup_after.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - test - org.springframework.web.servlet.DispatcherServlet - - contextInitializerClasses - - com.gopivotal.test,org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer - - - 1 - - diff --git a/spec/fixtures/web_servlet_existing_load_on_startup_before.xml b/spec/fixtures/web_servlet_existing_load_on_startup_before.xml deleted file mode 100644 index 3dcc96a8f6..0000000000 --- a/spec/fixtures/web_servlet_existing_load_on_startup_before.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - test - org.springframework.web.servlet.DispatcherServlet - - - contextInitializerClasses - - - com.gopivotal.test - - - 1 - - diff --git a/spec/fixtures/web_servlet_existing_params_after.xml b/spec/fixtures/web_servlet_existing_params_after.xml deleted file mode 100644 index 0185749bcc..0000000000 --- a/spec/fixtures/web_servlet_existing_params_after.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - test - org.springframework.web.servlet.DispatcherServlet - - contextInitializerClasses - - com.gopivotal.test,org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer - - - - diff --git a/spec/fixtures/web_servlet_existing_params_before.xml b/spec/fixtures/web_servlet_existing_params_before.xml deleted file mode 100644 index 028d5144a4..0000000000 --- a/spec/fixtures/web_servlet_existing_params_before.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - test - org.springframework.web.servlet.DispatcherServlet - - - contextInitializerClasses - - - com.gopivotal.test - - - - - diff --git a/spec/fixtures/web_servlet_load_on_startup_after.xml b/spec/fixtures/web_servlet_load_on_startup_after.xml deleted file mode 100644 index cf7ab6494f..0000000000 --- a/spec/fixtures/web_servlet_load_on_startup_after.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - test - org.springframework.web.servlet.DispatcherServlet - - contextInitializerClasses - - org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer - - - 1 - - diff --git a/spec/fixtures/web_servlet_load_on_startup_before.xml b/spec/fixtures/web_servlet_load_on_startup_before.xml deleted file mode 100644 index bd4f84d199..0000000000 --- a/spec/fixtures/web_servlet_load_on_startup_before.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - test - org.springframework.web.servlet.DispatcherServlet - 1 - - diff --git a/spec/fixtures/web_servlet_no_DispatcherServlet_after.xml b/spec/fixtures/web_servlet_no_DispatcherServlet_after.xml deleted file mode 100644 index 2d202ef74c..0000000000 --- a/spec/fixtures/web_servlet_no_DispatcherServlet_after.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - test - com.gopivotal.test.Servlet - - diff --git a/spec/fixtures/web_servlet_no_DispatcherServlet_before.xml b/spec/fixtures/web_servlet_no_DispatcherServlet_before.xml deleted file mode 100644 index 3d29784e57..0000000000 --- a/spec/fixtures/web_servlet_no_DispatcherServlet_before.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - test - com.gopivotal.test.Servlet - - - diff --git a/spec/fixtures/web_servlet_no_params_after.xml b/spec/fixtures/web_servlet_no_params_after.xml deleted file mode 100644 index 968fbf78ba..0000000000 --- a/spec/fixtures/web_servlet_no_params_after.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - test - org.springframework.web.servlet.DispatcherServlet - - contextInitializerClasses - - org.cloudfoundry.reconfiguration.CloudProfileApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudPropertySourceApplicationContextInitializer,org.cloudfoundry.reconfiguration.CloudServiceReconfigurationApplicationContextInitializer - - - - diff --git a/spec/fixtures/web_servlet_no_params_before.xml b/spec/fixtures/web_servlet_no_params_before.xml deleted file mode 100644 index 55f360cc8a..0000000000 --- a/spec/fixtures/web_servlet_no_params_before.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - test - org.springframework.web.servlet.DispatcherServlet - - - diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb deleted file mode 100644 index 215aec9fd1..0000000000 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier' - -describe JavaBuildpack::Framework::WebXmlModifier do - - it 'does not modify root if there is no ContextLoaderListener' do - assert_equality('web_root_no_contextLoaderListener', &:augment_root_context) - end - - it 'does not modify a servlet if is not a DispatcherServlet' do - assert_equality('web_servlet_no_DispatcherServlet', &:augment_root_context) - end - - it 'adds a new contextInitializerClasses if it does not exist' do - assert_equality('web_root_no_params', &:augment_root_context) - assert_equality('web_servlet_no_params', &:augment_servlet_contexts) - assert_equality('web_servlet_load_on_startup', &:augment_servlet_contexts) - end - - it 'updates existing contextInitializerClasses if it does exist' do - assert_equality('web_root_existing_params', &:augment_root_context) - assert_equality('web_servlet_existing_params', &:augment_servlet_contexts) - assert_equality('web_servlet_existing_load_on_startup', &:augment_servlet_contexts) - end - - def assert_equality(fixture) - modifier = described_class.new(Pathname.new("spec/fixtures/#{fixture}_before.xml").read) - - yield modifier - - actual = modifier.to_s - expected = Pathname.new("spec/fixtures/#{fixture}_after.xml").read - - expect(actual).to eq(expected) - end - -end diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index 1ea894f112..e58ed19d04 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -16,7 +16,6 @@ require 'spec_helper' require 'component_helper' require 'java_buildpack/framework/spring_auto_reconfiguration' -require 'java_buildpack/framework/spring_auto_reconfiguration/web_xml_modifier' describe JavaBuildpack::Framework::SpringAutoReconfiguration do include_context 'component_helper' @@ -67,26 +66,4 @@ expect(additional_libraries).to include(sandbox + "spring_auto_reconfiguration-#{version}.jar") end - context do - - let(:web_xml_modifier) { instance_double('WebXmlModifier') } - - before do - allow(JavaBuildpack::Framework::WebXmlModifier).to receive(:new).and_return(web_xml_modifier) - allow(web_xml_modifier).to receive(:augment_root_context) - allow(web_xml_modifier).to receive(:augment_servlet_contexts) - allow(web_xml_modifier).to receive(:to_s).and_return('Test Content') - end - - it 'updates web.xml if it exists', - app_fixture: 'framework_auto_reconfiguration_servlet_2', - cache_fixture: 'stub-auto-reconfiguration.jar' do - - component.compile - - expect((app_dir + 'WEB-INF/web.xml').read).to eq('Test Content') - end - - end - end From 1d37b9c042f8d7a141629875065f07185b498daf Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 9 Nov 2017 12:16:02 -0800 Subject: [PATCH 377/812] Upgrade to Container Customizer 2 This change updates the Container Customizer dependency to 2.+ in order to support Spring Boot 2. [resolves #518] --- config/container_customizer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/container_customizer.yml b/config/container_customizer.yml index ddcf7ce25c..c18a9878b8 100644 --- a/config/container_customizer.yml +++ b/config/container_customizer.yml @@ -15,5 +15,5 @@ # Configuration for the Container Customizer framework --- -version: 1.+ +version: 2.+ repository_root: "{default.repository.root}/container-customizer" From 972a559c786759ce101c9dc6c8def06efde6c929 Mon Sep 17 00:00:00 2001 From: Mike Youngstrom Date: Fri, 10 Nov 2017 11:27:15 -0700 Subject: [PATCH 378/812] Update JAVA_OPTS documentation Previously the JAVA_OPTS documentation erroneously stated that there were a set of allowed and disallowed memory arguments. With the advent of the new memory calculator all flags are now allowed. This change updates the docs to reflect that. [resolves #520] --- docs/framework-java_opts.md | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/docs/framework-java_opts.md b/docs/framework-java_opts.md index 2ecac96fda..5f03b83977 100644 --- a/docs/framework-java_opts.md +++ b/docs/framework-java_opts.md @@ -67,44 +67,32 @@ from_environment: false java_opts: -Xloggc:$PWD/beacon_gc.log -verbose:gc ``` -## Memory Settings - -The following `JAVA_OPTS` are restricted and will cause the application to fail deployment. - -* `-Xms` -* `-Xmx` -* `-Xss` -* `-XX:MaxMetaspaceSize` -* `-XX:MaxPermSize` -* `-XX:MetaspaceSize` -* `-XX:PermSize` - -### Allowed Memory Settings - -Setting any of the allowed memory settings may require a change to the [Memory Weightings]. Where a value is shown it is the default value for that setting. +## Allowed Memory Settings | Argument| Description | ------- | ----------- -| `-Xmn ` | Maximum size of young generation, known as the eden region. **This could effect the total heap size [Memory Weightings].** +| `-Xms` | Minimum or initial size of heap. +| `-Xss` | Size of each thread's stack. **This could effect the total heap size. [JRE Memory]** +| `-XX:MaxMetaspaceSize` | The maximum size Metaspace can grow to. **This could effect the total heap size. [JRE Memory]** +| `-XX:MaxPermSize` | The maximum size Permgen can grow to. Only applies to Java 7. **This could effect the total heap size. [JRE Memory]** +| `-Xmn ` | Maximum size of young generation, known as the eden region. | `-XX:+UseGCOverheadLimit` | Use a policy that limits the proportion of the VM's time that is spent in GC before an `java.lang.OutOfMemoryError` error is thrown. | `-XX:+UseLargePages` | Use large page memory. For details, see [Java Support for Large Memory Pages]. | `-XX:-HeapDumpOnOutOfMemoryError` | Dump heap to file when `java.lang.OutOfMemoryError` is thrown. | `-XX:HeapDumpPath=` | Path to directory or filename for heap dump. | `-XX:LargePageSizeInBytes=` | Sets the large page size used for the Java heap. -| `-XX:MaxDirectMemorySize=` | Upper limit on the maximum amount of allocatable direct buffer memory. **This could effect the [Memory Weightings].** +| `-XX:MaxDirectMemorySize=` | Upper limit on the maximum amount of allocatable direct buffer memory. **This could effect the total heap size. [JRE Memory]** | `-XX:MaxHeapFreeRatio=` | Maximum percentage of heap free after GC to avoid shrinking. -| `-XX:MaxNewSize=` | Maximum size of new generation. Since `1.4`, `MaxNewSize` is computed as a function of `NewRatio`. **This could effect the total heap size [Memory Weightings].** +| `-XX:MaxNewSize=` | Maximum size of new generation. Since `1.4`, `MaxNewSize` is computed as a function of `NewRatio`. | `-XX:MinHeapFreeRatio=` | Minimum percentage of heap free after GC to avoid expansion. | `-XX:NewRatio=` | Ratio of old/new generation sizes. 2 is equal to approximately 66%. -| `-XX:NewSize=` | Default size of new generation. **This could effect the total heap size [Memory Weightings].** +| `-XX:NewSize=` | Default size of new generation. | `-XX:OnError=";"` | Run user-defined commands on fatal error. -| `-XX:OnOutOfMemoryError=";"` | Run user-defined commands when an `java.lang.OutOfMemoryError` is first thrown. -| `-XX:ReservedCodeCacheSize=` | _Java 8 Only_ Maximum code cache size. Also know as `-Xmaxjitcodesize`. **This could effect the [Memory Weightings].** +| `-XX:ReservedCodeCacheSize=` | _Java 8 Only_ Maximum code cache size. Also know as `-Xmaxjitcodesize`. **This could effect the total heap size. [JRE Memory]** | `-XX:SurvivorRatio=` | Ratio of eden/survivor space. Solaris only. | `-XX:TargetSurvivorRatio=` | Desired ratio of survivor space used after scavenge. -| `-XX:ThreadStackSize=` | Thread stack size. (0 means use default stack size). [`config/java_opts.yml`]: ../config/java_opts.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Support for Large Memory Pages]: http://www.oracle.com/technetwork/java/javase/tech/largememory-jsp-137182.html -[Memory Weightings]: jre-open_jdk_jre.md#memory-weightings +[JRE Memory]: jre-open_jdk_jre.md#memory From 6d3933a0e1049c0a262f719dcc35544d2bd10ada Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 30 Nov 2017 10:06:00 -0800 Subject: [PATCH 379/812] Java 9 Support This change updates the buildpack for Java 9. This primarily involved dealing with the fact that security providers and extension directories are handled differently between Java 9 and all previous JREs. This change updates all users of these features to ensure that ext directories are not added and JARs that would be in those directories are added to the classpath in Java 9 and later. Note that this does not guarantee that all components will work in Java 9, just that the buildpack will build the proper environment to run an application. [#495] --- .../component/immutable_java_home.rb | 7 ++++ .../component/mutable_java_home.rb | 10 ++++- .../framework/container_security_provider.rb | 7 +++- .../framework/dyadic_ekm_security_provider.rb | 19 +++++++--- .../framework/luna_security_provider.rb | 8 +++- .../protect_app_security_provider.rb | 25 +++++++++++-- .../jre/open_jdk_like_security_providers.rb | 10 ++++- spec/droplet_helper.rb | 13 ++++++- .../component/immutable_java_home_spec.rb | 5 +++ .../component/mutable_java_home_spec.rb | 30 ++++++++++++--- .../container_security_provider_spec.rb | 32 ++++++++++++++++ .../dyadic_ekm_security_provider_spec.rb | 32 ++++++++++++++++ .../framework/luna_security_provider_spec.rb | 32 ++++++++++++++++ .../protect_app_security_provider_spec.rb | 37 +++++++++++++++++++ .../open_jdk_like_security_providers_spec.rb | 20 ++++++++++ 15 files changed, 267 insertions(+), 20 deletions(-) diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index f281cee47b..1d2f10a315 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -48,6 +48,13 @@ def java_8_or_later? @delegate.java_8_or_later? end + # Whether or not the version of Java is 9 or later + # + # @return [Boolean] +true+ iff the version is 9.0.0 or later + def java_9_or_later? + @delegate.java_9_or_later? + end + # @return [Pathname] the root of the droplet's +JAVA_HOME+ def root @delegate.root diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index 1df795e875..1cd4cfd5bd 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -39,9 +39,17 @@ def java_8_or_later? @version >= VERSION_8 end + # Whether or not the version of Java is 9 or later + # @return [Boolean] +true+ if and only if the version is 9.0.0 or later + def java_9_or_later? + @version >= VERSION_9 + end + VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0').freeze - private_constant :VERSION_8 + VERSION_9 = JavaBuildpack::Util::TokenizedVersion.new('9.0.0').freeze + + private_constant :VERSION_8, :VERSION_9 end diff --git a/lib/java_buildpack/framework/container_security_provider.rb b/lib/java_buildpack/framework/container_security_provider.rb index 52ceba930e..cadf261ac3 100644 --- a/lib/java_buildpack/framework/container_security_provider.rb +++ b/lib/java_buildpack/framework/container_security_provider.rb @@ -26,11 +26,16 @@ class ContainerSecurityProvider < JavaBuildpack::Component::VersionedDependencyC def compile download_jar @droplet.security_providers.insert 1, 'org.cloudfoundry.security.CloudFoundryContainerProvider' + @droplet.additional_libraries << (@droplet.sandbox + jar_name) if @droplet.java_home.java_9_or_later? end # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.extension_directories << @droplet.sandbox + if @droplet.java_home.java_9_or_later? + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + else + @droplet.extension_directories << @droplet.sandbox + end end protected diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index ebf240e4a5..4f56db95cb 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -32,13 +32,11 @@ def compile @droplet.copy_resources @droplet.security_providers << 'com.dyadicsec.provider.DYCryptoProvider' + @droplet.additional_libraries << dyadic_jar if @droplet.java_home.java_9_or_later? credentials = @application.services.find_service(FILTER, 'ca', 'key', 'recv_timeout', 'retries', 'send_timeout', 'servers')['credentials'] - write_key credentials['key'] - write_cert credentials['ca'] - write_conf credentials['servers'], credentials['send_timeout'], credentials['recv_timeout'], - credentials['retries'] + write_files(credentials) end # (see JavaBuildpack::Component::BaseComponent#release) @@ -46,7 +44,11 @@ def release @droplet.environment_variables .add_environment_variable 'LD_LIBRARY_PATH', @droplet.sandbox + 'usr/lib' - @droplet.extension_directories << ext_dir + if @droplet.java_home.java_9_or_later? + @droplet.additional_libraries << dyadic_jar + else + @droplet.extension_directories << ext_dir + end end protected @@ -107,6 +109,13 @@ def write_conf(servers, send_timeout, recv_timeout, retries) end end + def write_files(credentials) + write_key credentials['key'] + write_cert credentials['ca'] + write_conf credentials['servers'], credentials['send_timeout'], credentials['recv_timeout'], + credentials['retries'] + end + def write_key(key) FileUtils.mkdir_p key_file.parent key_file.open(File::CREAT | File::WRONLY) do |f| diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 435728804a..6833689493 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -32,6 +32,7 @@ def compile @droplet.copy_resources @droplet.security_providers << 'com.safenetinc.luna.provider.LunaProvider' + @droplet.additional_libraries << luna_provider_jar if @droplet.java_home.java_9_or_later? credentials = @application.services.find_service(FILTER, 'client', 'servers', 'groups')['credentials'] write_client credentials['client'] @@ -42,7 +43,12 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.environment_variables.add_environment_variable 'ChrystokiConfigurationPath', @droplet.sandbox - @droplet.extension_directories << ext_dir + + if @droplet.java_home.java_9_or_later? + @droplet.additional_libraries << luna_provider_jar + else + @droplet.extension_directories << ext_dir + end end protected diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb index 719bf22c30..914581c329 100644 --- a/lib/java_buildpack/framework/protect_app_security_provider.rb +++ b/lib/java_buildpack/framework/protect_app_security_provider.rb @@ -33,6 +33,7 @@ def compile @droplet.copy_resources @droplet.security_providers << 'com.ingrian.security.nae.IngrianProvider' + @droplet.additional_libraries << protect_app_jar if @droplet.java_home.java_9_or_later? credentials = @application.services.find_service(FILTER, 'client', 'trusted_certificates')['credentials'] @@ -44,7 +45,11 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - @droplet.extension_directories << @droplet.sandbox + 'ext' + if @droplet.java_home.java_9_or_later? + @droplet.additional_libraries << protect_app_jar + else + @droplet.extension_directories << ext_dir + end credentials = @application.services.find_service(FILTER)['credentials'] java_opts = @droplet.java_opts @@ -55,9 +60,7 @@ def release .add_system_property('com.ingrian.security.nae.Key_Store_Location', keystore) .add_system_property('com.ingrian.security.nae.Key_Store_Password', password) - credentials - .reject { |key, _| key =~ /^client$/ || key =~ /^trusted_certificates$/ } - .each { |key, value| java_opts.add_system_property("com.ingrian.security.nae.#{key}", value) } + add_additional_properties(credentials, java_opts) end protected @@ -73,6 +76,12 @@ def supports? private_constant :FILTER + def add_additional_properties(credentials, java_opts) + credentials + .reject { |key, _| key =~ /^client$/ || key =~ /^trusted_certificates$/ } + .each { |key, value| java_opts.add_system_property("com.ingrian.security.nae.#{key}", value) } + end + def add_client_credentials(pkcs12) shell "#{keytool} -importkeystore -noprompt -destkeystore #{keystore} -deststorepass #{password} " \ "-srckeystore #{pkcs12.path} -srcstorepass #{password} -srcstoretype pkcs12" \ @@ -88,6 +97,10 @@ def add_trusted_certificates(trusted_certificates) end end + def ext_dir + @droplet.sandbox + 'ext' + end + def keystore @droplet.sandbox + 'nae-keystore.jks' end @@ -113,6 +126,10 @@ def password 'nae-keystore-password' end + def protect_app_jar + ext_dir + "IngrianNAE-#{@version}.000.jar" + end + def write_certificate(certificate) Tempfile.open('certificate-') do |f| f.write "#{certificate}\n" diff --git a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb index fbd5bf2f32..89de601b85 100644 --- a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb +++ b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb @@ -36,16 +36,19 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release + return if @droplet.java_home.java_9_or_later? @droplet.extension_directories << java_security.parent.parent + 'ext' unless java_security.nil? end private + JAVA_9_SECURITY = 'conf/security/java.security'.freeze + JRE_SECURITY = 'lib/security/java.security'.freeze SERVER_JRE_SECURITY = 'jre/lib/security/java.security'.freeze - private_constant :JRE_SECURITY, :SERVER_JRE_SECURITY + private_constant :JAVA_9_SECURITY, :JRE_SECURITY, :SERVER_JRE_SECURITY def existing_security_providers(existing_security) JavaBuildpack::Util::Properties.new(existing_security) @@ -59,11 +62,16 @@ def index(entry) end def java_security + return java_9_security if @droplet.java_home.java_9_or_later? && java_9_security.exist? return jre_security if jre_security.exist? return server_jre_security if server_jre_security.exist? nil end + def java_9_security + @droplet.java_home.root + JAVA_9_SECURITY + end + def jre_security @droplet.java_home.root + JRE_SECURITY end diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index f85e860910..9d1c02f683 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -22,9 +22,11 @@ require 'java_buildpack/component/extension_directories' require 'java_buildpack/component/immutable_java_home' require 'java_buildpack/component/java_opts' +require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/component/networking' require 'java_buildpack/component/security_providers' require 'java_buildpack/util/snake_case' +require 'java_buildpack/util/tokenized_version' require 'pathname' shared_context 'droplet_helper' do @@ -48,8 +50,15 @@ let(:sandbox) { droplet.sandbox } let(:java_home) do - delegate = instance_double('MutableJavaHome', root: app_dir + '.test-java-home', version: %w[1 7 55 u60]) - JavaBuildpack::Component::ImmutableJavaHome.new delegate, app_dir + JavaBuildpack::Component::ImmutableJavaHome.new java_home_delegate, app_dir + end + + let(:java_home_delegate) do + delegate = JavaBuildpack::Component::MutableJavaHome.new + delegate.root = app_dir + '.test-java-home' + delegate.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_55') + + delegate end let(:environment_variables) do diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index 048cc0f0bc..1ce22fbed3 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -24,6 +24,7 @@ instance_double(JavaBuildpack::Component::MutableJavaHome, root: Pathname.new('test-java-home'), java_8_or_later?: true, + java_9_or_later?: true, version: JavaBuildpack::Util::TokenizedVersion.new('1.2.3_u04')) end @@ -45,4 +46,8 @@ expect(immutable_java_home.java_8_or_later?).to be end + it 'returns the delegate Java 9 or later' do + expect(immutable_java_home.java_9_or_later?).to be + end + end diff --git a/spec/java_buildpack/component/mutable_java_home_spec.rb b/spec/java_buildpack/component/mutable_java_home_spec.rb index 7b3d89ac40..ad063bde5c 100644 --- a/spec/java_buildpack/component/mutable_java_home_spec.rb +++ b/spec/java_buildpack/component/mutable_java_home_spec.rb @@ -36,24 +36,44 @@ expect(mutable_java_home.version).to eq(java_version) end - it 'recognizes Java 6' do + it 'recognizes Java 6 as earlier than Java 8' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.6.0') expect(mutable_java_home.java_8_or_later?).not_to be end - it 'recognizes Java 7' do + it 'recognizes Java 7 as earlier than Java 8' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0') expect(mutable_java_home.java_8_or_later?).not_to be end - it 'recognizes Java 8' do + it 'recognizes Java 8 as later than or equal to Java 8' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0') expect(mutable_java_home.java_8_or_later?).to be end - it 'recognizes Java 9' do - mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.9.0') + it 'recognizes Java 9 as later than or equal to Java 8' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') expect(mutable_java_home.java_8_or_later?).to be end + it 'recognizes Java 6 as earlier than Java 9' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.6.0') + expect(mutable_java_home.java_9_or_later?).not_to be + end + + it 'recognizes Java 7 as earlier than Java 9' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0') + expect(mutable_java_home.java_9_or_later?).not_to be + end + + it 'recognizes Java 8 as earlier than Java 9' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0') + expect(mutable_java_home.java_9_or_later?).not_to be + end + + it 'recognizes Java 9 as later than or equal to Java 9' do + mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') + expect(mutable_java_home.java_9_or_later?).to be + end + end diff --git a/spec/java_buildpack/framework/container_security_provider_spec.rb b/spec/java_buildpack/framework/container_security_provider_spec.rb index cfd7f46e3a..735c55a473 100644 --- a/spec/java_buildpack/framework/container_security_provider_spec.rb +++ b/spec/java_buildpack/framework/container_security_provider_spec.rb @@ -37,4 +37,36 @@ expect(security_providers[1]).to eq('org.cloudfoundry.security.CloudFoundryContainerProvider') end + context do + + let(:java_home_delegate) do + delegate = JavaBuildpack::Component::MutableJavaHome.new + delegate.root = app_dir + '.test-java-home' + delegate.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') + + delegate + end + + it 'adds JAR to classpath during compile in Java 9', + cache_fixture: 'stub-container-security-provider.jar' do + + component.compile + + expect(additional_libraries).to include(droplet.sandbox + "container_security_provider-#{version}.jar") + end + + it 'adds JAR to classpath during release in Java 9' do + component.release + + expect(additional_libraries).to include(droplet.sandbox + "container_security_provider-#{version}.jar") + end + + it 'adds does not add extension directory in Java 9' do + component.release + + expect(extension_directories).not_to include(droplet.sandbox) + end + + end + end diff --git a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb index a0e0ff4e9e..551531fa2a 100644 --- a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb +++ b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb @@ -100,6 +100,38 @@ expect(extension_directories).to include(droplet.sandbox + 'ext') end + context do + + let(:java_home_delegate) do + delegate = JavaBuildpack::Component::MutableJavaHome.new + delegate.root = app_dir + '.test-java-home' + delegate.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') + + delegate + end + + it 'adds JAR to classpath during compile in Java 9', + cache_fixture: 'stub-dyadic-ekm-security-provider.tar.gz' do + + component.compile + + expect(additional_libraries).to include(droplet.sandbox + 'usr/lib/dsm/dsm-advapi-1.0.jar') + end + + it 'adds JAR to classpath during release in Java 9' do + component.release + + expect(additional_libraries).to include(droplet.sandbox + 'usr/lib/dsm/dsm-advapi-1.0.jar') + end + + it 'adds does not add extension directory in Java 9' do + component.release + + expect(extension_directories).not_to include(droplet.sandbox + 'ext') + end + + end + def check_file_contents(actual, expected) expect(File.read(actual)).to eq File.read(expected) end diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index 54080cf3c0..5ca5f7b125 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -124,6 +124,38 @@ expect(extension_directories).to include(droplet.sandbox + 'ext') end + context do + + let(:java_home_delegate) do + delegate = JavaBuildpack::Component::MutableJavaHome.new + delegate.root = app_dir + '.test-java-home' + delegate.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') + + delegate + end + + it 'adds JAR to classpath during compile in Java 9', + cache_fixture: 'stub-luna-security-provider.tar' do + + component.compile + + expect(additional_libraries).to include(droplet.sandbox + 'jsp/LunaProvider.jar') + end + + it 'adds JAR to classpath during release in Java 9' do + component.release + + expect(additional_libraries).to include(droplet.sandbox + 'jsp/LunaProvider.jar') + end + + it 'adds does not add extension directory in Java 9' do + component.release + + expect(extension_directories).not_to include(droplet.sandbox + 'ext') + end + + end + context do let(:configuration) { { 'logging_enabled' => true, 'ha_logging_enabled' => true } } diff --git a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb index 345866405d..5fb6884198 100644 --- a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb +++ b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb @@ -111,5 +111,42 @@ expect(java_opts).not_to include(start_with('-Dcom.ingrian.security.nae.trusted_certificates')) end + context do + + let(:java_home_delegate) do + delegate = JavaBuildpack::Component::MutableJavaHome.new + delegate.root = app_dir + '.test-java-home' + delegate.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') + + delegate + end + + it 'adds JAR to classpath during compile in Java 9', + cache_fixture: 'stub-protect-app-security-provider.zip' do + + allow(component).to receive(:shell).with(start_with('unzip -qq')).and_call_original + allow(component).to receive(:shell).with(start_with('openssl pkcs12')) + allow(component).to receive(:shell).with(start_with("#{java_home.root}/bin/keytool -importkeystore")) + allow(component).to receive(:shell).with(start_with("#{java_home.root}/bin/keytool -importcert")) + + component.compile + + expect(additional_libraries).to include(droplet.sandbox + "ext/IngrianNAE-#{version}.000.jar") + end + + it 'adds JAR to classpath during release in Java 9' do + component.release + + expect(additional_libraries).to include(droplet.sandbox + "ext/IngrianNAE-#{version}.000.jar") + end + + it 'adds does not add extension directory in Java 9' do + component.release + + expect(extension_directories).not_to include(droplet.sandbox + 'ext') + end + + end + end end diff --git a/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb b/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb index 19776575c7..277bef1a80 100644 --- a/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb @@ -63,4 +63,24 @@ expect(extension_directories).to include(java_home.root + 'jre/lib/ext') end + context do + + let(:java_home_delegate) do + delegate = JavaBuildpack::Component::MutableJavaHome.new + delegate.root = app_dir + '.test-java-home' + delegate.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') + + delegate + end + + it 'does not add extension directory for Java 9' do + extension_directories.clear + + component.release + + expect(extension_directories).to be_empty + end + + end + end From 8d947657b67f8076a1cc114d8abfc71dbd39050f Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 30 Nov 2017 10:49:40 -0800 Subject: [PATCH 380/812] IntelliJ Upgrade --- .idea/codeStyleSettings.xml | 23 ----------------------- .idea/codeStyles/Project.xml | 19 +++++++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 +++++ 3 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 .idea/codeStyleSettings.xml create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml deleted file mode 100644 index 8daae40f5e..0000000000 --- a/.idea/codeStyleSettings.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000000..6b46d21ce6 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000000..79ee123c2b --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file From 0fc33ece2edaf1d30b76cca56cd9fe4be3d23ebd Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Mon, 20 Nov 2017 16:38:26 -0500 Subject: [PATCH 381/812] Check for Roles when retrieving operator credentials Previously, the implementation hard-coded the expected username of 'cluster- operator' for connections. Changes to the service are coming that will allow alternate usernames to be used. This change updates the code to properly handle those alternate usernames so long as they have the cluster-operator role. [resolves #523][#151847755] Signed-off-by: Rebecca Chin Signed-off-by: Emily Casey Signed-off-by: Gavin Enns --- .../container/tomcat/tomcat_geode_store.rb | 8 +++- .../tomcat/tomcat_geode_store_spec.rb | 42 +++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index aec5594dbc..a6cf494f75 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -38,9 +38,9 @@ def compile def release return unless supports? credentials = @application.services.find_service(FILTER, KEY_LOCATORS, KEY_USERS)['credentials'] - user = credentials[KEY_USERS].find { |u| u['username'] == 'cluster_operator' } + user = credentials[KEY_USERS].find { |u| cluster_operator?(u) } - @droplet.java_opts.add_system_property 'gemfire.security-username', 'cluster_operator' + @droplet.java_opts.add_system_property 'gemfire.security-username', user['username'] @droplet.java_opts.add_system_property 'gemfire.security-password', user['password'] @droplet.java_opts.add_system_property 'gemfire.security-client-auth-init', 'io.pivotal.cloudcache.ClientAuthInitialize.create' @@ -78,6 +78,10 @@ def supports? :CACHE_CLIENT_LISTENER_CLASS_NAME, :SCHEMA_URL, :SCHEMA_INSTANCE_URL, :SCHEMA_LOCATION, :LOCATOR_REGEXP, :FUNCTION_SERVICE_CLASS_NAMES + def cluster_operator?(user) + user['username'] == 'cluster_operator' || user['roles'] && (user['roles'].include? 'cluster_operator') + end + def add_client_cache(document) client_cache = document.add_element 'client-cache', 'xmlns' => SCHEMA_URL, diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index f70f763b27..4a062eb3eb 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -41,8 +41,11 @@ 'locators' => ['some-locator[some-port]', 'some-other-locator[some-other-port]'], 'users' => [ - { 'password' => 'fake-password', - 'username' => 'cluster_operator' } + { + 'password' => 'some-password', + 'username' => 'some-username', + 'roles' => ['cluster_operator'] + } ] } ) @@ -102,9 +105,40 @@ expect(java_opts).to include( '-Dgemfire.security-client-auth-init=io.pivotal.cloudcache.ClientAuthInitialize.create' ) - expect(java_opts).to include('-Dgemfire.security-username=cluster_operator') - expect(java_opts).to include('-Dgemfire.security-password=fake-password') + expect(java_opts).to include('-Dgemfire.security-username=some-username') + expect(java_opts).to include('-Dgemfire.security-password=some-password') end + end + context 'when there is session replication service and service credentials do not include roles' do + before do + allow(services).to receive(:one_service?).with(/session-replication/, 'locators', 'users') + .and_return(true) + allow(services).to receive(:find_service).and_return( + 'credentials' => { + 'locators' => ['some-locator[some-port]', 'some-other-locator[some-other-port]'], + 'users' => + [ + { + 'password' => 'some-password', + 'username' => 'cluster_operator' + } + ] + } + ) + end + + it 'assumes usernames represent roles and passes security properties to the release', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store.tar' do + + component.release + + expect(java_opts).to include( + '-Dgemfire.security-client-auth-init=io.pivotal.cloudcache.ClientAuthInitialize.create' + ) + expect(java_opts).to include('-Dgemfire.security-username=cluster_operator') + expect(java_opts).to include('-Dgemfire.security-password=some-password') + end end end From 6a3361a39678360919223f4accf7251ae400b6dc Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 1 Dec 2017 10:17:49 -0800 Subject: [PATCH 382/812] Polishing --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index ea627d4188..2b5ba4d2e8 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -41,4 +41,4 @@ redis_store: connection_pool_size: 2 geode_store: version: 0.+ - repository_root: "https://repo.spring.io/ext-release-local/geode-store" + repository_root: https://repo.spring.io/ext-release-local/geode-store From c1b315b95cdfad04258ba5d774b2a8a127d5d7f8 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 8 Dec 2017 11:34:06 -0800 Subject: [PATCH 383/812] Update Metrics Writer This change updates the version of the metrics writer to the new major version, supporting micrometer. --- config/metric_writer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/metric_writer.yml b/config/metric_writer.yml index a69d3a2b19..a09d0ea4c4 100644 --- a/config/metric_writer.yml +++ b/config/metric_writer.yml @@ -15,5 +15,5 @@ # Metric Writer configuration --- -version: 1.+ +version: 2.+ repository_root: "{default.repository.root}/metric-writer" From a1dbb9c0885261aad9df6407c11b79d43d47c878 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 11 Dec 2017 15:05:58 -0800 Subject: [PATCH 384/812] Retry with Exponential Backoff Previously, when a download failed for a network reason, it would be retried up to 5 times, but they would happen as quickly as possible after the failure. Given that network errors are transient but typically take a perceptible amount of time this retry almost always experienced the same error every single time. This change adds an exponential backoff to the retry behavior waiting between 5 and 60 seconds as more retried are attempted. [resolves #524] --- .../util/cache/download_cache.rb | 51 ++++++++++++------- .../util/cache/download_cache_spec.rb | 6 ++- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index f81d958993..b595dbc093 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -40,6 +40,8 @@ module Cache # * {http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html HTTP/1.1 Header Field Definitions} class DownloadCache + attr_writer :retry_max + # Creates an instance of the cache that is backed by a number of filesystem locations. The first argument # (+mutable_cache_root+) is the only location that downloaded files will be stored in. # @@ -51,6 +53,7 @@ def initialize(mutable_cache_root = Pathname.new(Dir.tmpdir), *immutable_cache_r @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger DownloadCache @mutable_cache_root = mutable_cache_root @immutable_cache_roots = immutable_cache_roots.unshift mutable_cache_root + @retry_max = RETRY_MAX end # Retrieves an item from the cache. Yields an open file containing the item's content or raises an exception if @@ -118,7 +121,11 @@ def evict(uri) Net::HTTPTemporaryRedirect ].freeze - private_constant :CA_FILE, :FAILURE_LIMIT, :HTTP_ERRORS, :REDIRECT_TYPES + RETRY_MAX = 60 + + RETRY_MIN = 5 + + private_constant :CA_FILE, :FAILURE_LIMIT, :HTTP_ERRORS, :REDIRECT_TYPES, :RETRY_MAX, :RETRY_MIN def attempt(http, request, cached_file) downloaded = false @@ -144,6 +151,26 @@ def attempt(http, request, cached_file) downloaded end + def attempt_update(cached_file, http, uri) + request = request uri, cached_file + request.basic_auth uri.user, uri.password if uri.user && uri.password + + failures = 0 + begin + attempt http, request, cached_file + rescue InferredNetworkFailure, *HTTP_ERRORS => e + if (failures += 1) > FAILURE_LIMIT + InternetAvailability.instance.available false, "Request failed: #{e.message}" + raise e + else + delay = calculate_delay failures + @logger.warn { "Request failure #{failures}, retrying after #{delay}s. Failure: #{e.message}" } + sleep delay + retry + end + end + end + def ca_file(http_options) return unless CA_FILE.exist? http_options[:ca_file] = CA_FILE.to_s @@ -192,6 +219,10 @@ def cache_last_modified(response, cached_file) end end + def calculate_delay(failures) + [@retry_max, RETRY_MIN * (2**(failures - 1))].min + end + def client_authentication(http_options) client_authentication = JavaBuildpack::Util::ConfigurationUtils.load('cache')['client_authentication'] @@ -319,24 +350,6 @@ def update(uri, cached_file) end end - def attempt_update(cached_file, http, uri) - request = request uri, cached_file - request.basic_auth uri.user, uri.password if uri.user && uri.password - - failures = 0 - begin - attempt http, request, cached_file - rescue InferredNetworkFailure, *HTTP_ERRORS => e - if (failures += 1) > FAILURE_LIMIT - InternetAvailability.instance.available false, "Request failed: #{e.message}" - raise e - else - @logger.warn { "Request failure #{failures}, retrying. Failure: #{e.message}" } - retry - end - end - end - def validate_size(expected_size, cached_file) return unless expected_size diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 8ac03eae3e..687bf3b032 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -39,7 +39,11 @@ let(:uri_secure) { 'https://foo-uri/' } - let(:download_cache) { described_class.new(mutable_cache_root, immutable_cache_root) } + let(:download_cache) do + download_cache = described_class.new(mutable_cache_root, immutable_cache_root) + download_cache.retry_max = 0 + download_cache + end before do described_class.const_set :CA_FILE, ca_certs_directory From fd3fed24257dc8208a4462d1d875e23163dd0ac8 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 12 Dec 2017 09:02:04 -0800 Subject: [PATCH 385/812] Reduce Expected Thread Count Previously, the expected thread count (used for memory calculations) was set at 300. This was the Tomcat default 200 plus 100 "other" threads. I've been suitably convinced that the "other" collection is closer to 50 than it is to 100 even accounting for connection pools and the like. This change updates the default to 250 which will reclaim 50M be default, and we'll see how it goes. --- config/open_jdk_jre.yml | 2 +- config/oracle_jre.yml | 2 +- config/zulu_jre.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index e8b5a534fc..f495ec3bd0 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -26,4 +26,4 @@ memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" class_count: - stack_threads: 300 + stack_threads: 250 diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index a451c45090..8cde27244d 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -29,4 +29,4 @@ memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" class_count: - stack_threads: 300 + stack_threads: 250 diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 339ff16b1d..15e809d472 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -29,4 +29,4 @@ memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" class_count: - stack_threads: 300 + stack_threads: 250 From 78d69e1819c86e44ccf2da8e2cf8168edd74445c Mon Sep 17 00:00:00 2001 From: stipx Date: Wed, 15 Nov 2017 15:43:52 +0100 Subject: [PATCH 386/812] Dynatrace OneAgent integration skiperrors flag In order to be able to run the app even if the agent download fails there is now a "skiperrors" flag which can be set to "true" in the service credentials. This flag is disabled by default and should only be used if there is no other option. [#526] --- docs/framework-dynatrace_one_agent.md | 1 + .../framework/dynatrace_one_agent.rb | 69 ++++++++++++++----- .../framework/dynatrace_one_agent_spec.rb | 48 +++++++++++++ 3 files changed, 100 insertions(+), 18 deletions(-) diff --git a/docs/framework-dynatrace_one_agent.md b/docs/framework-dynatrace_one_agent.md index 4580bb2e3e..08d8739557 100644 --- a/docs/framework-dynatrace_one_agent.md +++ b/docs/framework-dynatrace_one_agent.md @@ -28,6 +28,7 @@ The credential payload of the service may contain the following entries: | `apitoken` | The token for integrating your Dynatrace environment with Cloud Foundry. You can find it in the deploy Dynatrace section within your environment. | `apiurl` | (Optional) The base URL of the Dynatrace API. If you are using Dynatrace Managed you will need to set this property to `https:///e//api`. If you are using Dynatrace SaaS you don't need to set this property. | `environmentid` | Your Dynatrace environment ID is the unique identifier of your Dynatrace environment. You can find it in the deploy Dynatrace section within your environment. +| `skiperrors` | (Optional) The errors during agent download are skipped and the injection is disabled. Use this option at your own risk. Possible values are 'true' and 'false'. This option is disabled by default! ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 6ca3014de6..b13cc09c1f 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -31,14 +31,24 @@ class DynatraceOneAgent < JavaBuildpack::Component::VersionedDependencyComponent def initialize(context) super(context) @version, @uri = agent_download_url if supports? + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger DynatraceOneAgent end # (see JavaBuildpack::Component::BaseComponent#compile) def compile - JavaBuildpack::Util::Cache::InternetAvailability.instance.available( - true, 'The Dynatrace One Agent download location is always accessible' - ) do - download(@version, @uri) { |file| expand file } + begin + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, 'The Dynatrace One Agent download location is always accessible' + ) do + download(@version, @uri) { |file| expand file } + end + rescue StandardError => e + raise unless skip_errors? + + @logger.error { "Dynatrace OneAgent download failed: #{e}" } + @logger.warn { "Agent injection disabled because of #{SKIP_ERRORS} credential is set to true!" } + FileUtils.mkdir_p(File.dirname(error_file)) + File.write(error_file, e.to_s) end @droplet.copy_resources @@ -46,19 +56,16 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, APITOKEN, ENVIRONMENTID)['credentials'] - environment_variables = @droplet.environment_variables - manifest = agent_manifest + if File.exist?(error_file) + @logger.warn { "Dynatrace OneAgent injection disabled due to download error: #{File.read(error_file)}" } + return + end - @droplet.java_opts.add_agentpath(agent_path(manifest)) + manifest = agent_manifest - environment_variables - .add_environment_variable(DT_TENANT, credentials[ENVIRONMENTID]) - .add_environment_variable(DT_TENANTTOKEN, tenanttoken(manifest)) - .add_environment_variable(DT_CONNECTION_POINT, endpoints(manifest)) + @droplet.java_opts.add_agentpath(agent_path(manifest)) - environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) unless application_id? - environment_variables.add_environment_variable(DT_HOST_ID, host_id) unless host_id? + dynatrace_environment_variables(manifest) end protected @@ -88,13 +95,15 @@ def supports? FILTER = /dynatrace/ + SKIP_ERRORS = 'skiperrors'.freeze + private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_HOST_ID, :DT_TENANT, - :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER + :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :SKIP_ERRORS def agent_download_url - credentials = @application.services.find_service(FILTER, APITOKEN, ENVIRONMENTID)['credentials'] - download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ - "&bitness=64&Api-Token=#{credentials[APITOKEN]}" + creds = credentials + download_uri = "#{api_base_url(creds)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ + "&bitness=64&Api-Token=#{creds[APITOKEN]}" ['latest', download_uri] end @@ -121,10 +130,30 @@ def application_id? @application.environment.key?(DT_APPLICATION_ID) end + def credentials + @application.services.find_service(FILTER, APITOKEN, ENVIRONMENTID)['credentials'] + end + + def dynatrace_environment_variables(manifest) + environment_variables = @droplet.environment_variables + + environment_variables + .add_environment_variable(DT_TENANT, credentials[ENVIRONMENTID]) + .add_environment_variable(DT_TENANTTOKEN, tenanttoken(manifest)) + .add_environment_variable(DT_CONNECTION_POINT, endpoints(manifest)) + + environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) unless application_id? + environment_variables.add_environment_variable(DT_HOST_ID, host_id) unless host_id? + end + def endpoints(manifest) "\"#{manifest['communicationEndpoints'].join(';')}\"" end + def error_file + @droplet.sandbox + 'dynatrace_download_error' + end + def expand(file) with_timing "Expanding Dynatrace OneAgent to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do Dir.mktmpdir do |root| @@ -143,6 +172,10 @@ def host_id? @application.environment.key?(DT_HOST_ID) end + def skip_errors? + 'true'.casecmp(credentials[SKIP_ERRORS] || 'false').zero? + end + def tenanttoken(manifest) manifest['tenantToken'] end diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 7d115d92f5..44fc737c6b 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -92,6 +92,54 @@ end + context do + + before do + allow(services).to receive(:one_service?).with(/dynatrace/, 'apitoken', 'environmentid').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-environmentid', + 'apiurl' => 'test-apiurl', + 'apitoken' => 'test-apitoken' }) + allow(application_cache).to receive(:get) + .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64' \ + '&Api-Token=test-apitoken') + .and_raise(RuntimeError.new('service interrupt')) + end + + it 'fails on download error on default' do + expect { component.compile }.to raise_error(RuntimeError) + end + + end + + context do + + before do + allow(services).to receive(:one_service?).with(/dynatrace/, 'apitoken', 'environmentid').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-environmentid', + 'apiurl' => 'test-apiurl', + 'apitoken' => 'test-apitoken', + 'skiperrors' => 'true' }) + allow(application_cache).to receive(:get) + .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64' \ + '&Api-Token=test-apitoken') + .and_raise(RuntimeError.new('service interrupt')) + end + + it 'skips errors during compile and writes error file' do + component.compile + expect(sandbox + 'dynatrace_download_error').to exist + end + + it 'does not do anything during release' do + component.compile + component.release + + expect(java_opts).not_to include('-agentpath:$PWD/.java-buildpack/dynatrace_one_agent/agent/lib64/' \ + 'liboneagentloader.so') + end + + end + end end From c3023e9158153b919b27f6d7efea24579ef2c8f1 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 14 Dec 2017 11:15:22 -0800 Subject: [PATCH 387/812] Polishing [resolves #526] --- .../framework/dynatrace_one_agent.rb | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index b13cc09c1f..704984440e 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -17,6 +17,7 @@ require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' require 'java_buildpack/util/cache/internet_availability' +require 'java_buildpack/util/to_b' require 'json' module JavaBuildpack @@ -36,27 +37,25 @@ def initialize(context) # (see JavaBuildpack::Component::BaseComponent#compile) def compile - begin - JavaBuildpack::Util::Cache::InternetAvailability.instance.available( - true, 'The Dynatrace One Agent download location is always accessible' - ) do - download(@version, @uri) { |file| expand file } - end - rescue StandardError => e - raise unless skip_errors? - - @logger.error { "Dynatrace OneAgent download failed: #{e}" } - @logger.warn { "Agent injection disabled because of #{SKIP_ERRORS} credential is set to true!" } - FileUtils.mkdir_p(File.dirname(error_file)) - File.write(error_file, e.to_s) + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, 'The Dynatrace One Agent download location is always accessible' + ) do + download(@version, @uri) { |file| expand file } end @droplet.copy_resources + rescue StandardError => e + raise unless skip_errors? + + @logger.error { "Dynatrace OneAgent download failed: #{e}" } + @logger.warn { "Agent injection disabled because of #{SKIP_ERRORS} credential is set to true!" } + FileUtils.mkdir_p(error_file.parent) + File.write(error_file, e.to_s) end # (see JavaBuildpack::Component::BaseComponent#release) def release - if File.exist?(error_file) + if error_file.exist? @logger.warn { "Dynatrace OneAgent injection disabled due to download error: #{File.read(error_file)}" } return end @@ -101,9 +100,8 @@ def supports? :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :SKIP_ERRORS def agent_download_url - creds = credentials - download_uri = "#{api_base_url(creds)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ - "&bitness=64&Api-Token=#{creds[APITOKEN]}" + download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ + "&bitness=64&Api-Token=#{credentials[APITOKEN]}" ['latest', download_uri] end @@ -173,7 +171,7 @@ def host_id? end def skip_errors? - 'true'.casecmp(credentials[SKIP_ERRORS] || 'false').zero? + credentials[SKIP_ERRORS].to_b end def tenanttoken(manifest) From db64526b718b2f8d0e66ee5ea034b8259e181c85 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 21 Dec 2017 09:53:41 -0800 Subject: [PATCH 388/812] Dependency Updates This change updates the buildpack with new development dependencies. In addition, it updates the code to be compliant with the new version of Rubocop. --- .rubocop.yml | 4 +- Gemfile.lock | 61 +++++++++---------- java-buildpack.iml | 38 ++++++------ lib/java_buildpack/buildpack.rb | 2 +- lib/java_buildpack/buildpack_version.rb | 20 +++--- .../framework/contrast_security_agent.rb | 2 - .../framework/dyadic_ekm_security_provider.rb | 4 +- .../framework/luna_security_provider.rb | 32 +++++----- lib/java_buildpack/jre/open_jdk_like_jre.rb | 4 +- lib/java_buildpack/logging/logger_factory.rb | 6 +- .../repository/configured_item.rb | 2 +- .../util/cache/download_cache.rb | 2 +- lib/java_buildpack/util/file_enumerable.rb | 2 +- lib/java_buildpack/util/groovy_utils.rb | 2 +- lib/java_buildpack/util/properties.rb | 2 +- rakelib/dependency_cache_task.rb | 4 +- spec/application_helper.rb | 2 +- spec/bin/compile_spec.rb | 4 +- spec/bin/detect_spec.rb | 2 +- spec/bin/release_spec.rb | 2 +- spec/component_helper.rb | 12 ++-- spec/console_helper.rb | 2 +- spec/droplet_helper.rb | 6 +- spec/integration_helper.rb | 8 +-- spec/internet_availability_helper.rb | 4 +- spec/java_buildpack/buildpack_spec.rb | 4 +- spec/java_buildpack/buildpack_version_spec.rb | 6 +- .../component/additional_libraries_spec.rb | 2 +- .../component/application_spec.rb | 2 +- .../component/base_component_spec.rb | 2 +- spec/java_buildpack/component/droplet_spec.rb | 4 +- .../component/environment_variables_spec.rb | 2 +- .../component/extension_directories_spec.rb | 2 +- .../component/java_opts_spec.rb | 2 +- .../component/modular_component_spec.rb | 2 +- .../component/security_providers_spec.rb | 2 +- .../java_buildpack/component/services_spec.rb | 30 ++++----- .../versioned_dependency_component_spec.rb | 2 +- .../container/dist_zip_like_spec.rb | 2 +- .../java_buildpack/container/dist_zip_spec.rb | 2 +- spec/java_buildpack/container/groovy_spec.rb | 2 +- .../container/java_main_spec.rb | 8 +-- .../container/play_framework_spec.rb | 2 +- spec/java_buildpack/container/ratpack_spec.rb | 2 +- .../container/spring_boot_cli_spec.rb | 2 +- .../container/spring_boot_spec.rb | 2 +- .../tomcat_access_logging_support_spec.rb | 2 +- .../tomcat_external_configuration_spec.rb | 2 +- .../tomcat/tomcat_geode_store_spec.rb | 2 +- .../tomcat/tomcat_insight_support_spec.rb | 2 +- .../container/tomcat/tomcat_instance_spec.rb | 2 +- .../tomcat/tomcat_lifecycle_support_spec.rb | 2 +- .../tomcat/tomcat_logging_support_spec.rb | 2 +- .../tomcat/tomcat_redis_store_spec.rb | 2 +- spec/java_buildpack/container/tomcat_spec.rb | 2 +- .../framework/app_dynamics_agent_spec.rb | 2 +- .../framework/aspectj_weaver_agent_spec.rb | 2 +- .../client_certificate_mapper_spec.rb | 2 +- .../framework/container_customizer_spec.rb | 2 +- .../container_security_provider_spec.rb | 2 +- .../framework/contrast_security_agent_spec.rb | 4 +- spec/java_buildpack/framework/debug_spec.rb | 2 +- .../dyadic_ekm_security_provider_spec.rb | 2 +- .../framework/dynatrace_appmon_agent_spec.rb | 2 +- .../framework/dynatrace_one_agent_spec.rb | 2 +- .../google_stackdriver_debugger_spec.rb | 2 +- .../framework/introscope_agent_spec.rb | 2 +- .../java_memory_assistant/agent_spec.rb | 6 +- .../java_memory_assistant/clean_up_spec.rb | 4 +- .../heap_dump_folder_spec.rb | 6 +- .../framework/java_memory_assistant_spec.rb | 2 +- .../framework/java_opts_spec.rb | 2 +- .../framework/java_security_spec.rb | 2 +- spec/java_buildpack/framework/jmx_spec.rb | 2 +- .../framework/jrebel_agent_spec.rb | 2 +- .../framework/luna_security_provider_spec.rb | 2 +- .../framework/maria_db_jdbc_spec.rb | 2 +- .../framework/metric_writer_spec.rb | 2 +- .../framework/multi_buildpack_spec.rb | 2 +- .../framework/new_relic_agent_spec.rb | 2 +- .../framework/postgresql_jdbc_spec.rb | 2 +- .../protect_app_security_provider_spec.rb | 2 +- .../spring_auto_reconfiguration_spec.rb | 2 +- .../framework/spring_insight_spec.rb | 4 +- .../framework/takipi_agent_spec.rb | 6 +- .../framework/your_kit_profiler_spec.rb | 2 +- .../jre/ibm_jre_initializer_spec.rb | 2 +- spec/java_buildpack/jre/ibm_jre_spec.rb | 2 +- spec/java_buildpack/jre/jvmkill_agent_spec.rb | 2 +- .../jre/open_jdk_like_jre_spec.rb | 2 +- .../open_jdk_like_memory_calculator_spec.rb | 2 +- .../open_jdk_like_security_providers_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_spec.rb | 2 +- .../logging/delegating_logger_spec.rb | 2 +- .../logging/logger_factory_spec.rb | 4 +- .../repository/repository_index_spec.rb | 4 +- .../repository/version_resolver_spec.rb | 2 +- .../util/cache/application_cache_spec.rb | 8 +-- .../util/cache/cache_factory_spec.rb | 6 +- .../util/cache/cached_file_spec.rb | 2 +- .../util/cache/download_cache_spec.rb | 26 ++++---- .../util/cache/internet_availability_spec.rb | 4 +- .../util/configuration_utils_spec.rb | 2 +- .../util/filtering_pathname_spec.rb | 2 +- .../util/java_main_utils_spec.rb | 4 +- spec/java_buildpack/util/play/base_spec.rb | 2 +- spec/java_buildpack/util/play/factory_spec.rb | 4 +- .../util/play/post22_dist_spec.rb | 2 +- spec/java_buildpack/util/play/post22_spec.rb | 2 +- .../util/play/post22_staged_spec.rb | 2 +- .../util/play/pre22_dist_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_spec.rb | 4 +- .../util/play/pre22_staged_spec.rb | 2 +- .../java_buildpack/util/ratpack_utils_spec.rb | 2 +- spec/java_buildpack/util/sanitize_spec.rb | 2 +- spec/java_buildpack/util/shell_spec.rb | 2 +- .../util/spring_boot_utils_spec.rb | 2 +- spec/logging_helper.rb | 6 +- spec/memory_limit_helper.rb | 2 +- 119 files changed, 262 insertions(+), 265 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index e9846b9ead..d099153199 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,7 +7,7 @@ AllCops: - 'rakelib/**/*' Exclude: - 'build/**/*' - - Gemfile # TODO: Remove when upgrading to any version after 0.48.1 + - Gemfile Layout/EmptyLinesAroundBlockBody: Exclude: - 'spec/**/*.rb' @@ -50,5 +50,7 @@ RSpec/NestedGroups: Max: 4 Style/Documentation: Enabled: false +Style/FormatStringToken: + Enabled: false Style/MethodMissing: Enabled: false diff --git a/Gemfile.lock b/Gemfile.lock index 65d9bc33f4..7ec4ee399c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,56 +1,55 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.5.1) - public_suffix (~> 2.0, >= 2.0.2) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) ast (2.3.0) crack (0.4.3) safe_yaml (~> 1.0.0) diff-lcs (1.3) - hashdiff (0.3.4) - parallel (1.11.2) - parser (2.4.0.0) - ast (~> 2.2) + hashdiff (0.3.7) + parallel (1.12.1) + parser (2.4.0.2) + ast (~> 2.3) powerpack (0.1.1) - public_suffix (2.0.5) - rainbow (2.2.2) - rake - rake (12.0.0) + public_suffix (3.0.1) + rainbow (3.0.0) + rake (12.3.0) redcarpet (3.4.0) - rspec (3.6.0) - rspec-core (~> 3.6.0) - rspec-expectations (~> 3.6.0) - rspec-mocks (~> 3.6.0) - rspec-core (3.6.0) - rspec-support (~> 3.6.0) - rspec-expectations (3.6.0) + rspec (3.7.0) + rspec-core (~> 3.7.0) + rspec-expectations (~> 3.7.0) + rspec-mocks (~> 3.7.0) + rspec-core (3.7.0) + rspec-support (~> 3.7.0) + rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-mocks (3.6.0) + rspec-support (~> 3.7.0) + rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-support (3.6.0) - rubocop (0.49.1) + rspec-support (~> 3.7.0) + rspec-support (3.7.0) + rubocop (0.52.0) parallel (~> 1.10) - parser (>= 2.3.3.1, < 3.0) + parser (>= 2.4.0.2, < 3.0) powerpack (~> 0.1) - rainbow (>= 1.99.1, < 3.0) + rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.15.1) - rubocop (>= 0.42.0) - ruby-progressbar (1.8.1) + rubocop-rspec (1.21.0) + rubocop (>= 0.52.0) + ruby-progressbar (1.9.0) rubyzip (1.2.1) safe_yaml (1.0.4) tee (1.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - unicode-display_width (1.2.1) - webmock (3.0.1) + unicode-display_width (1.3.0) + webmock (3.1.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - yard (0.9.9) + yard (0.9.12) PLATFORMS ruby @@ -68,4 +67,4 @@ DEPENDENCIES yard BUNDLED WITH - 1.15.1 + 1.16.0 diff --git a/java-buildpack.iml b/java-buildpack.iml index df0d76f182..a9b05c4a98 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -267,34 +267,34 @@ - + - + - - - + + + - - - + + + - - - - - - - - + + + + + + + + - - - + + +
diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 0a19c140d5..850628dbc0 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -260,7 +260,7 @@ def with_buildpack(app_dir, message) application = Component::Application.new(app_dir) yield new(app_dir, application) if block_given? - rescue => e + rescue StandardError => e handle_error(e, message) end diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index c2bedc3f52..411e4b7327 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -46,9 +46,9 @@ class BuildpackVersion # Creates a new instance def initialize(should_log = true) configuration = JavaBuildpack::Util::ConfigurationUtils.load('version', true, should_log) - @hash = configuration['hash'] || hash + @hash = configuration['hash'] || calculate_hash @offline = configuration['offline'] || ENV['OFFLINE'].to_b - @remote = configuration['remote'] || remote + @remote = configuration['remote'] || calculate_remote @version = configuration['version'] || ENV['VERSION'] || @hash return unless should_log @@ -102,8 +102,12 @@ def to_s(human_readable = true) private_constant :GIT_DIR - def remote_string - "#{@remote}##{@hash}" if @remote && !@remote.empty? && @hash && !@hash.empty? + def calculate_hash + git 'rev-parse --short HEAD' + end + + def calculate_remote + git 'config --get remote.origin.url' end def git(command) @@ -122,12 +126,8 @@ def git_dir? GIT_DIR.exist? end - def hash - git 'rev-parse --short HEAD' - end - - def remote - git 'config --get remote.origin.url' + def remote_string + "#{@remote}##{@hash}" if @remote && !@remote.empty? && @hash && !@hash.empty? end end diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index 297f485ffa..2c50c26067 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -1,5 +1,3 @@ -# Encoding: utf-8 - # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index 4f56db95cb..28db59f265 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -99,13 +99,13 @@ def write_cert(cert) def write_conf(servers, send_timeout, recv_timeout, retries) FileUtils.mkdir_p conf_file.parent conf_file.open(File::CREAT | File::WRONLY) do |f| - f.write < e + rescue StandardError => e raise RuntimeError, "#{component_name} error: #{e.message}", e.backtrace end diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index b595dbc093..09f533b9e1 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -263,7 +263,7 @@ def from_mutable_cache(uri) cached_file = CachedFile.new @mutable_cache_root, uri, true cached = update URI(uri), cached_file [cached_file, cached] - rescue => e + rescue StandardError => e @logger.warn { "Unable to download #{uri.sanitize_uri} into cache #{@mutable_cache_root}: #{e.message}" } nil end diff --git a/lib/java_buildpack/util/file_enumerable.rb b/lib/java_buildpack/util/file_enumerable.rb index 8f1381717d..3d8d8ed94e 100644 --- a/lib/java_buildpack/util/file_enumerable.rb +++ b/lib/java_buildpack/util/file_enumerable.rb @@ -62,7 +62,7 @@ def select(candidates, &block) def open(default, candidate, &block) candidate.open('r', external_encoding: 'UTF-8', &block) - rescue => e + rescue StandardError => e @logger.warn e.message default end diff --git a/lib/java_buildpack/util/groovy_utils.rb b/lib/java_buildpack/util/groovy_utils.rb index 8095fc4dae..1f8a6432b4 100644 --- a/lib/java_buildpack/util/groovy_utils.rb +++ b/lib/java_buildpack/util/groovy_utils.rb @@ -74,7 +74,7 @@ def groovy_files(application) def safe_read(file) yield - rescue => e + rescue StandardError => e raise "Unable to read file #{file.path}: #{e.message}" end diff --git a/lib/java_buildpack/util/properties.rb b/lib/java_buildpack/util/properties.rb index 972945c300..7960389ca5 100644 --- a/lib/java_buildpack/util/properties.rb +++ b/lib/java_buildpack/util/properties.rb @@ -26,7 +26,7 @@ class Properties < Hash # @param [Pathname, nil] file_name the file to use for initialization. If no file is passed in, the instance is # empty. def initialize(file_name) - return self if file_name.nil? + return if file_name.nil? contents = file_name.open(&:read) contents.gsub!(/[\r\n\f]+ /, '') diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 312cd36dd0..4149f1cd60 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -100,7 +100,7 @@ def cache def cache_task(uri) task uri do |t| @monitor.synchronize { rake_output_message "Caching #{t.name}" } - cache.get(t.name) {} + cache.get(t.name){} end uri @@ -192,7 +192,7 @@ def update_configuration(config, version, sub_component) elsif config.key?(sub_component) config[sub_component]['version'] = version else - config.values.each { |v| update_configuration(v, version, sub_component) if v.is_a? Hash } + config.each_value { |v| update_configuration(v, version, sub_component) if v.is_a? Hash } end end diff --git a/spec/application_helper.rb b/spec/application_helper.rb index cf067d1f0a..f1bb34b65b 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/services' require 'json' -shared_context 'application_helper' do +shared_context 'with application help' do let(:app_dir) { Pathname.new Dir.mktmpdir } diff --git a/spec/bin/compile_spec.rb b/spec/bin/compile_spec.rb index 3e10209234..5c59df207c 100644 --- a/spec/bin/compile_spec.rb +++ b/spec/bin/compile_spec.rb @@ -18,8 +18,8 @@ require 'memory_limit_helper' describe 'compile script', :integration do # rubocop:disable RSpec/DescribeClass - include_context 'integration_helper' - include_context 'memory_limit_helper' + include_context 'with integration help' + include_context 'with memory limit help' it 'returns zero if success', app_fixture: 'integration_valid', diff --git a/spec/bin/detect_spec.rb b/spec/bin/detect_spec.rb index 0c522eea58..907a5e6127 100644 --- a/spec/bin/detect_spec.rb +++ b/spec/bin/detect_spec.rb @@ -17,7 +17,7 @@ require 'integration_helper' describe 'detect script', :integration do # rubocop:disable RSpec/DescribeClass - include_context 'integration_helper' + include_context 'with integration help' it 'returns zero if success', app_fixture: 'integration_valid' do diff --git a/spec/bin/release_spec.rb b/spec/bin/release_spec.rb index 2441956bbf..375c6595be 100644 --- a/spec/bin/release_spec.rb +++ b/spec/bin/release_spec.rb @@ -17,7 +17,7 @@ require 'integration_helper' describe 'release script', :integration do # rubocop:disable RSpec/DescribeClass - include_context 'integration_helper' + include_context 'with integration help' it 'returns zero if success', app_fixture: 'integration_valid' do diff --git a/spec/component_helper.rb b/spec/component_helper.rb index 3aa984fb13..8a46cee1f6 100644 --- a/spec/component_helper.rb +++ b/spec/component_helper.rb @@ -25,12 +25,12 @@ require 'java_buildpack/util/tokenized_version' require 'pathname' -shared_context 'component_helper' do - include_context 'application_helper' - include_context 'console_helper' - include_context 'droplet_helper' - include_context 'internet_availability_helper' - include_context 'logging_helper' +shared_context 'with component help' do + include_context 'with application help' + include_context 'with console help' + include_context 'with droplet help' + include_context 'with internet availability help' + include_context 'with logging help' let(:application_cache) { instance_double('ApplicationCache') } diff --git a/spec/console_helper.rb b/spec/console_helper.rb index 75f921f735..fa4e9e8020 100644 --- a/spec/console_helper.rb +++ b/spec/console_helper.rb @@ -17,7 +17,7 @@ require 'tee' require 'java_buildpack/util/colorize' -shared_context 'console_helper' do +shared_context 'with console help' do STDOUT.sync STDERR.sync diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index 9d1c02f683..da1ec95ac3 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -29,9 +29,9 @@ require 'java_buildpack/util/tokenized_version' require 'pathname' -shared_context 'droplet_helper' do - include_context 'application_helper' - include_context 'logging_helper' +shared_context 'with droplet help' do + include_context 'with application help' + include_context 'with logging help' let(:additional_libraries) { JavaBuildpack::Component::AdditionalLibraries.new app_dir } diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index 56dc793a71..0b5b784049 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -19,10 +19,10 @@ require 'logging_helper' require 'open3' -shared_context 'integration_helper' do - include_context 'application_helper' - include_context 'console_helper' - include_context 'logging_helper' +shared_context 'with integration help' do + include_context 'with application help' + include_context 'with console help' + include_context 'with logging help' let(:buildpack_dir) { Pathname.new Dir.mktmpdir } diff --git a/spec/internet_availability_helper.rb b/spec/internet_availability_helper.rb index a033165b29..8c8aaae689 100644 --- a/spec/internet_availability_helper.rb +++ b/spec/internet_availability_helper.rb @@ -17,8 +17,8 @@ require 'logging_helper' require 'java_buildpack/util/cache/internet_availability' -shared_context 'internet_availability_helper' do - include_context 'logging_helper' +shared_context 'with internet availability help' do + include_context 'with logging help' # Re-initialize internet availability before do |example| diff --git a/spec/java_buildpack/buildpack_spec.rb b/spec/java_buildpack/buildpack_spec.rb index c65e26a84b..4d033aa836 100644 --- a/spec/java_buildpack/buildpack_spec.rb +++ b/spec/java_buildpack/buildpack_spec.rb @@ -20,8 +20,8 @@ require 'java_buildpack/component/base_component' describe JavaBuildpack::Buildpack do - include_context 'application_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with logging help' let(:stub_container1) { instance_double('StubContainer1', detect: nil, component_name: 'StubContainer1') } diff --git a/spec/java_buildpack/buildpack_version_spec.rb b/spec/java_buildpack/buildpack_version_spec.rb index b4bc723a3d..da936b8ccf 100644 --- a/spec/java_buildpack/buildpack_version_spec.rb +++ b/spec/java_buildpack/buildpack_version_spec.rb @@ -20,9 +20,9 @@ require 'pathname' describe JavaBuildpack::BuildpackVersion do - include_context 'application_helper' - include_context 'console_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with console help' + include_context 'with logging help' let(:buildpack_version) { described_class.new } diff --git a/spec/java_buildpack/component/additional_libraries_spec.rb b/spec/java_buildpack/component/additional_libraries_spec.rb index 36df0ffbda..e151c3a02a 100644 --- a/spec/java_buildpack/component/additional_libraries_spec.rb +++ b/spec/java_buildpack/component/additional_libraries_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/additional_libraries' describe JavaBuildpack::Component::AdditionalLibraries do - include_context 'droplet_helper' + include_context 'with droplet help' context do diff --git a/spec/java_buildpack/component/application_spec.rb b/spec/java_buildpack/component/application_spec.rb index 6978414c87..585c4a7529 100644 --- a/spec/java_buildpack/component/application_spec.rb +++ b/spec/java_buildpack/component/application_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/component/application' describe JavaBuildpack::Component::Application do - include_context 'application_helper' + include_context 'with application help' it 'returns a parsed version of VCAP_APPLICATION as details' do expect(application.details).to eq(vcap_application) diff --git a/spec/java_buildpack/component/base_component_spec.rb b/spec/java_buildpack/component/base_component_spec.rb index bebb65a858..90654cbd97 100644 --- a/spec/java_buildpack/component/base_component_spec.rb +++ b/spec/java_buildpack/component/base_component_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/base_component' describe JavaBuildpack::Component::BaseComponent do - include_context 'component_helper' + include_context 'with component help' let(:component) { StubBaseComponent.new context } diff --git a/spec/java_buildpack/component/droplet_spec.rb b/spec/java_buildpack/component/droplet_spec.rb index 5ac020902b..ed68ee3ff4 100644 --- a/spec/java_buildpack/component/droplet_spec.rb +++ b/spec/java_buildpack/component/droplet_spec.rb @@ -21,8 +21,8 @@ require 'pathname' describe JavaBuildpack::Component::Droplet do - include_context 'application_helper' - include_context 'droplet_helper' + include_context 'with application help' + include_context 'with droplet help' it 'returns additional_libraries' do expect(droplet.additional_libraries).to equal(additional_libraries) diff --git a/spec/java_buildpack/component/environment_variables_spec.rb b/spec/java_buildpack/component/environment_variables_spec.rb index 7a8affd1bf..1e890d24ea 100644 --- a/spec/java_buildpack/component/environment_variables_spec.rb +++ b/spec/java_buildpack/component/environment_variables_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/environment_variables' describe JavaBuildpack::Component::EnvironmentVariables do - include_context 'droplet_helper' + include_context 'with droplet help' let(:variables) { described_class.new droplet.root } diff --git a/spec/java_buildpack/component/extension_directories_spec.rb b/spec/java_buildpack/component/extension_directories_spec.rb index 622d5ce89b..23879f276c 100644 --- a/spec/java_buildpack/component/extension_directories_spec.rb +++ b/spec/java_buildpack/component/extension_directories_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/extension_directories' describe JavaBuildpack::Component::ExtensionDirectories do - include_context 'droplet_helper' + include_context 'with droplet help' context do diff --git a/spec/java_buildpack/component/java_opts_spec.rb b/spec/java_buildpack/component/java_opts_spec.rb index 674aee2f61..286dee4d42 100644 --- a/spec/java_buildpack/component/java_opts_spec.rb +++ b/spec/java_buildpack/component/java_opts_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/java_opts' describe JavaBuildpack::Component::JavaOpts do - include_context 'droplet_helper' + include_context 'with droplet help' let(:opts) { described_class.new droplet.root } diff --git a/spec/java_buildpack/component/modular_component_spec.rb b/spec/java_buildpack/component/modular_component_spec.rb index bcb1a16e91..edc37d4b2d 100644 --- a/spec/java_buildpack/component/modular_component_spec.rb +++ b/spec/java_buildpack/component/modular_component_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/modular_component' describe JavaBuildpack::Component::ModularComponent do - include_context 'component_helper' + include_context 'with component help' let(:component) { StubModularComponent.new context } diff --git a/spec/java_buildpack/component/security_providers_spec.rb b/spec/java_buildpack/component/security_providers_spec.rb index 5c7c12ce29..d118d04050 100644 --- a/spec/java_buildpack/component/security_providers_spec.rb +++ b/spec/java_buildpack/component/security_providers_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/security_providers' describe JavaBuildpack::Component::SecurityProviders do - include_context 'droplet_helper' + include_context 'with droplet help' context do diff --git a/spec/java_buildpack/component/services_spec.rb b/spec/java_buildpack/component/services_spec.rb index 2a144f17b9..174a750299 100644 --- a/spec/java_buildpack/component/services_spec.rb +++ b/spec/java_buildpack/component/services_spec.rb @@ -18,13 +18,13 @@ require 'java_buildpack/component/services' describe JavaBuildpack::Component::Services do - include_context 'logging_helper' + include_context 'with logging help' let(:services) { described_class.new('test' => service_payload) } - context('find_service') do + context('when find_service') do - context('single service') do + context('with single service') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', @@ -53,7 +53,7 @@ end - context('two services') do + context('with two services') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan' }, @@ -85,9 +85,9 @@ end - context('find_volume_service') do + context('with find_volume_service') do - context('single service') do + context('with single service') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', @@ -119,7 +119,7 @@ end - context('two services') do + context('with two services') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', @@ -156,9 +156,9 @@ end - context('one_service') do + context('with one_service') do - context('single service') do + context('with single service') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', @@ -212,7 +212,7 @@ end - context('two services') do + context('with two services') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan' }, @@ -269,9 +269,9 @@ end - context('one_volume_service') do + context('with one_volume_service') do - context('no volume mounts') do + context('with no volume mounts') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] @@ -294,7 +294,7 @@ end - context('empty volume mounts') do + context('with empty volume mounts') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, @@ -318,7 +318,7 @@ end - context('one volume mount') do + context('with one volume mount') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, @@ -344,7 +344,7 @@ end - context('two volume mounts') do + context('with two volume mounts') do let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, diff --git a/spec/java_buildpack/component/versioned_dependency_component_spec.rb b/spec/java_buildpack/component/versioned_dependency_component_spec.rb index 6eba9d6f04..c39b7ce75c 100644 --- a/spec/java_buildpack/component/versioned_dependency_component_spec.rb +++ b/spec/java_buildpack/component/versioned_dependency_component_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/component/versioned_dependency_component' describe JavaBuildpack::Component::VersionedDependencyComponent do - include_context 'component_helper' + include_context 'with component help' let(:component) { StubVersionedDependencyComponent.new context } diff --git a/spec/java_buildpack/container/dist_zip_like_spec.rb b/spec/java_buildpack/container/dist_zip_like_spec.rb index 498bb3bcf7..257174dc75 100644 --- a/spec/java_buildpack/container/dist_zip_like_spec.rb +++ b/spec/java_buildpack/container/dist_zip_like_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/dist_zip_like' describe JavaBuildpack::Container::DistZipLike do - include_context 'component_helper' + include_context 'with component help' it 'raises error if id method is unimplemented' do expect { component.send(:id) }.to raise_error "Method 'id' must be defined" diff --git a/spec/java_buildpack/container/dist_zip_spec.rb b/spec/java_buildpack/container/dist_zip_spec.rb index 7feba8d203..a54ba549d9 100644 --- a/spec/java_buildpack/container/dist_zip_spec.rb +++ b/spec/java_buildpack/container/dist_zip_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/dist_zip' describe JavaBuildpack::Container::DistZip do - include_context 'component_helper' + include_context 'with component help' it 'detects a distZip application', app_fixture: 'container_dist_zip' do diff --git a/spec/java_buildpack/container/groovy_spec.rb b/spec/java_buildpack/container/groovy_spec.rb index 8068c1a091..38c15383d0 100644 --- a/spec/java_buildpack/container/groovy_spec.rb +++ b/spec/java_buildpack/container/groovy_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/groovy' describe JavaBuildpack::Container::Groovy do - include_context 'component_helper' + include_context 'with component help' it 'does not detect a non-Groovy project', app_fixture: 'container_main' do diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index e7af6291c9..24803fe1b2 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -20,14 +20,14 @@ describe JavaBuildpack::Container::JavaMain do include JavaBuildpack::Util - include_context 'component_helper' + include_context 'with component help' - shared_context 'explicit_main_class' do + shared_context 'with explicit main class' do let(:configuration) { { 'java_main_class' => 'test-java-main-class' } } end context do - include_context 'explicit_main_class' + include_context 'with explicit main class' it 'detects with main class configuration' do @@ -72,7 +72,7 @@ end context do - include_context 'explicit_main_class' + include_context 'with explicit main class' it 'returns command' do diff --git a/spec/java_buildpack/container/play_framework_spec.rb b/spec/java_buildpack/container/play_framework_spec.rb index b65f1f91a8..4544c90904 100644 --- a/spec/java_buildpack/container/play_framework_spec.rb +++ b/spec/java_buildpack/container/play_framework_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/util/play/factory' describe JavaBuildpack::Container::PlayFramework do - include_context 'component_helper' + include_context 'with component help' let(:delegate) { instance_double('delegate') } diff --git a/spec/java_buildpack/container/ratpack_spec.rb b/spec/java_buildpack/container/ratpack_spec.rb index bec5e54178..0e2755c06b 100644 --- a/spec/java_buildpack/container/ratpack_spec.rb +++ b/spec/java_buildpack/container/ratpack_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/ratpack' describe JavaBuildpack::Container::Ratpack do - include_context 'component_helper' + include_context 'with component help' it 'detects a dist Ratpack application', app_fixture: 'container_ratpack_dist' do diff --git a/spec/java_buildpack/container/spring_boot_cli_spec.rb b/spec/java_buildpack/container/spring_boot_cli_spec.rb index b4059a8453..2cd48f38cb 100644 --- a/spec/java_buildpack/container/spring_boot_cli_spec.rb +++ b/spec/java_buildpack/container/spring_boot_cli_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/spring_boot_cli' describe JavaBuildpack::Container::SpringBootCLI do - include_context 'component_helper' + include_context 'with component help' it 'does not detect a non-Groovy project', app_fixture: 'container_main' do diff --git a/spec/java_buildpack/container/spring_boot_spec.rb b/spec/java_buildpack/container/spring_boot_spec.rb index 8ecd6e8ab3..c7cae87c38 100644 --- a/spec/java_buildpack/container/spring_boot_spec.rb +++ b/spec/java_buildpack/container/spring_boot_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/spring_boot' describe JavaBuildpack::Container::SpringBoot do - include_context 'component_helper' + include_context 'with component help' it 'detects a dist Spring Boot application', app_fixture: 'container_spring_boot_dist' do diff --git a/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb index 348327d2d3..33fecef2bc 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/tomcat/tomcat_access_logging_support' describe JavaBuildpack::Container::TomcatAccessLoggingSupport do - include_context 'component_helper' + include_context 'with component help' let(:component_id) { 'tomcat' } diff --git a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb index ac747917b1..1831b7de03 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/tomcat/tomcat_external_configuration' describe JavaBuildpack::Container::TomcatExternalConfiguration do - include_context 'component_helper' + include_context 'with component help' let(:component_id) { 'tomcat' } diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index 4a062eb3eb..8ed2df5667 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/tomcat/tomcat_geode_store' describe JavaBuildpack::Container::TomcatGeodeStore do - include_context 'component_helper' + include_context 'with component help' let(:component_id) { 'tomcat' } diff --git a/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb index f2d00a960e..0aad953da4 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/container/tomcat/tomcat_insight_support' describe JavaBuildpack::Container::TomcatInsightSupport do - include_context 'component_helper' + include_context 'with component help' let(:component_id) { 'tomcat' } diff --git a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb index c41b36c0b1..fda99b2eb1 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/tomcat/tomcat_instance' describe JavaBuildpack::Container::TomcatInstance do - include_context 'component_helper' + include_context 'with component help' let(:component_id) { 'tomcat' } diff --git a/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb index c080303da2..92744a6b28 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/tomcat/tomcat_lifecycle_support' describe JavaBuildpack::Container::TomcatLifecycleSupport do - include_context 'component_helper' + include_context 'with component help' let(:component_id) { 'tomcat' } diff --git a/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb index 9adc96b27c..281294826f 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/tomcat/tomcat_logging_support' describe JavaBuildpack::Container::TomcatLoggingSupport do - include_context 'component_helper' + include_context 'with component help' let(:component_id) { 'tomcat' } diff --git a/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb index 65bbd9f411..41956341d3 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/container/tomcat/tomcat_redis_store' describe JavaBuildpack::Container::TomcatRedisStore do - include_context 'component_helper' + include_context 'with component help' let(:component_id) { 'tomcat' } diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index 657d090a35..3e3133aac4 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -26,7 +26,7 @@ require 'java_buildpack/container/tomcat/tomcat_redis_store' describe JavaBuildpack::Container::Tomcat do - include_context 'component_helper' + include_context 'with component help' let(:component) { StubTomcat.new context } diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 1cc192e5f6..adfedaed0a 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/app_dynamics_agent' describe JavaBuildpack::Framework::AppDynamicsAgent do - include_context 'component_helper' + include_context 'with component help' let(:configuration) do { 'default_tier_name' => nil, diff --git a/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb b/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb index 112013ae3b..b48fb34bb7 100644 --- a/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb +++ b/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/aspectj_weaver_agent' describe JavaBuildpack::Framework::AspectjWeaverAgent do - include_context 'component_helper' + include_context 'with component help' it 'does not detect if not enabled' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb index c4483379e0..17afbf62d1 100644 --- a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb +++ b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/client_certificate_mapper' describe JavaBuildpack::Framework::ClientCertificateMapper do - include_context 'component_helper' + include_context 'with component help' it 'always detects' do expect(component.detect).to eq("client-certificate-mapper=#{version}") diff --git a/spec/java_buildpack/framework/container_customizer_spec.rb b/spec/java_buildpack/framework/container_customizer_spec.rb index 37f53879a1..354a77b002 100644 --- a/spec/java_buildpack/framework/container_customizer_spec.rb +++ b/spec/java_buildpack/framework/container_customizer_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/container_customizer' describe JavaBuildpack::Framework::ContainerCustomizer do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without Spring Boot WAR' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/container_security_provider_spec.rb b/spec/java_buildpack/framework/container_security_provider_spec.rb index 735c55a473..5f1dd60180 100644 --- a/spec/java_buildpack/framework/container_security_provider_spec.rb +++ b/spec/java_buildpack/framework/container_security_provider_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/container_security_provider' describe JavaBuildpack::Framework::ContainerSecurityProvider do - include_context 'component_helper' + include_context 'with component help' it 'always detects' do expect(component.detect).to eq("container-security-provider=#{version}") diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb index 8ea1ec57c4..088767234f 100644 --- a/spec/java_buildpack/framework/contrast_security_agent_spec.rb +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -1,5 +1,3 @@ -# Encoding: utf-8 - # Cloud Foundry Java Buildpack # Copyright 2013-2016 the original author or authors. # @@ -21,7 +19,7 @@ require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Framework::ContrastSecurityAgent do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without contrastsecurity service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/debug_spec.rb b/spec/java_buildpack/framework/debug_spec.rb index fd361165fe..23d0640edc 100644 --- a/spec/java_buildpack/framework/debug_spec.rb +++ b/spec/java_buildpack/framework/debug_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/debug' describe JavaBuildpack::Framework::Debug do - include_context 'component_helper' + include_context 'with component help' it 'does not detect if not enabled' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb index 551531fa2a..a8213658b3 100644 --- a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb +++ b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/dyadic_ekm_security_provider' describe JavaBuildpack::Framework::DyadicEkmSecurityProvider do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without dyadic-n/a service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb index f3475fa342..e3b27e647d 100644 --- a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/dynatrace_appmon_agent' describe JavaBuildpack::Framework::DynatraceAppmonAgent do - include_context 'component_helper' + include_context 'with component help' let(:configuration) do { 'default_agent_name' => nil } diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 44fc737c6b..8f5445f61c 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Framework::DynatraceOneAgent do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without dynatrace-n/a service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb b/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb index d7b719b58d..d848661562 100644 --- a/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb +++ b/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/google_stackdriver_debugger' describe JavaBuildpack::Framework::GoogleStackdriverDebugger do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without google-stackdriver-debugger-n/a service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index 90b5147668..d3a79e567e 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/introscope_agent' describe JavaBuildpack::Framework::IntroscopeAgent do - include_context 'component_helper' + include_context 'with component help' let(:configuration) do { 'default_agent_name' => "$(expr \"$VCAP_APPLICATION\" : '.*application_name[\": ]*\\([A-Za-z0-9_-]*\\).*')" } diff --git a/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb index 564d3a06ac..63e8c55762 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb @@ -21,9 +21,9 @@ require 'java_buildpack/framework/java_memory_assistant/agent' describe JavaBuildpack::Framework::JavaMemoryAssistantAgent do - include_context 'application_helper' - include_context 'component_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with component help' + include_context 'with logging help' let(:vcap_application) do { diff --git a/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb index 9aeb77a524..0c3046dc8c 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb @@ -19,8 +19,8 @@ require 'java_buildpack/framework/java_memory_assistant/clean_up' describe JavaBuildpack::Framework::JavaMemoryAssistantCleanUp do - include_context 'application_helper' - include_context 'component_helper' + include_context 'with application help' + include_context 'with component help' let(:version) { '1.2.3' } diff --git a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb index 62c8ce1968..a3d59ce6e4 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb @@ -20,9 +20,9 @@ require 'java_buildpack/framework/java_memory_assistant/heap_dump_folder' describe JavaBuildpack::Framework::JavaMemoryAssistantHeapDumpFolder do - include_context 'application_helper' - include_context 'component_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with component help' + include_context 'with logging help' let(:logger) { described_class.instance.get_logger String } diff --git a/spec/java_buildpack/framework/java_memory_assistant_spec.rb b/spec/java_buildpack/framework/java_memory_assistant_spec.rb index 32f73e3933..74e9f32b5e 100644 --- a/spec/java_buildpack/framework/java_memory_assistant_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant_spec.rb @@ -22,7 +22,7 @@ require 'java_buildpack/framework/java_memory_assistant/heap_dump_folder' describe JavaBuildpack::Framework::JavaMemoryAssistant do - include_context 'component_helper' + include_context 'with component help' let(:component) { StubJavaMemoryAssistant.new context } diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index bb2a324a19..c4394c54ea 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/java_opts' describe JavaBuildpack::Framework::JavaOpts do - include_context 'component_helper' + include_context 'with component help' context do let(:configuration) { { 'java_opts' => '-Xmx1024M' } } diff --git a/spec/java_buildpack/framework/java_security_spec.rb b/spec/java_buildpack/framework/java_security_spec.rb index 050298461e..f28dd1e5e8 100644 --- a/spec/java_buildpack/framework/java_security_spec.rb +++ b/spec/java_buildpack/framework/java_security_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/framework/java_security' describe JavaBuildpack::Framework::JavaSecurity do - include_context 'component_helper' + include_context 'with component help' it 'adds extension directories to system properties' do component.release diff --git a/spec/java_buildpack/framework/jmx_spec.rb b/spec/java_buildpack/framework/jmx_spec.rb index aec788dd68..0354feca60 100644 --- a/spec/java_buildpack/framework/jmx_spec.rb +++ b/spec/java_buildpack/framework/jmx_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/jmx' describe JavaBuildpack::Framework::Jmx do - include_context 'component_helper' + include_context 'with component help' it 'does not detect if not enabled' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb index 8ba330ba36..4bb3b4ee19 100644 --- a/spec/java_buildpack/framework/jrebel_agent_spec.rb +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/jrebel_agent' describe JavaBuildpack::Framework::JrebelAgent do - include_context 'component_helper' + include_context 'with component help' it 'does not detect when rebel-remote.xml is not present' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index 5ca5f7b125..c0066f6700 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/luna_security_provider' describe JavaBuildpack::Framework::LunaSecurityProvider do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without luna-n/a service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/maria_db_jdbc_spec.rb b/spec/java_buildpack/framework/maria_db_jdbc_spec.rb index c92cdbe371..896e509274 100644 --- a/spec/java_buildpack/framework/maria_db_jdbc_spec.rb +++ b/spec/java_buildpack/framework/maria_db_jdbc_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/maria_db_jdbc' describe JavaBuildpack::Framework::MariaDbJDBC do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without a service containing a mysql tag' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/metric_writer_spec.rb b/spec/java_buildpack/framework/metric_writer_spec.rb index f18362228a..bc3f631d97 100644 --- a/spec/java_buildpack/framework/metric_writer_spec.rb +++ b/spec/java_buildpack/framework/metric_writer_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/metric_writer' describe JavaBuildpack::Framework::MetricWriter do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without metric-forwarder service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/multi_buildpack_spec.rb b/spec/java_buildpack/framework/multi_buildpack_spec.rb index 2094e221e3..ff64b3497f 100644 --- a/spec/java_buildpack/framework/multi_buildpack_spec.rb +++ b/spec/java_buildpack/framework/multi_buildpack_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/framework/multi_buildpack' describe JavaBuildpack::Framework::MultiBuildpack do - include_context 'component_helper' + include_context 'with component help' before do allow(Pathname).to receive(:glob).with('/tmp/*/deps').and_return([Pathname.new(app_dir)]) diff --git a/spec/java_buildpack/framework/new_relic_agent_spec.rb b/spec/java_buildpack/framework/new_relic_agent_spec.rb index 2f9c719f93..305a6dfe90 100644 --- a/spec/java_buildpack/framework/new_relic_agent_spec.rb +++ b/spec/java_buildpack/framework/new_relic_agent_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Framework::NewRelicAgent do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without newrelic-n/a service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/postgresql_jdbc_spec.rb b/spec/java_buildpack/framework/postgresql_jdbc_spec.rb index 706bd6105a..cc2eb7d4bf 100644 --- a/spec/java_buildpack/framework/postgresql_jdbc_spec.rb +++ b/spec/java_buildpack/framework/postgresql_jdbc_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/postgresql_jdbc' describe JavaBuildpack::Framework::PostgresqlJDBC do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without a postgres service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb index 5fb6884198..8f3e80aad5 100644 --- a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb +++ b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/protect_app_security_provider' describe JavaBuildpack::Framework::ProtectAppSecurityProvider do - include_context 'component_helper' + include_context 'with component help' it 'does not detect without protectapp-n/a service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index e58ed19d04..8015044207 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/spring_auto_reconfiguration' describe JavaBuildpack::Framework::SpringAutoReconfiguration do - include_context 'component_helper' + include_context 'with component help' let(:configuration) { { 'enabled' => true } } diff --git a/spec/java_buildpack/framework/spring_insight_spec.rb b/spec/java_buildpack/framework/spring_insight_spec.rb index 678867652f..ddd889eb34 100644 --- a/spec/java_buildpack/framework/spring_insight_spec.rb +++ b/spec/java_buildpack/framework/spring_insight_spec.rb @@ -20,8 +20,8 @@ require 'java_buildpack/framework/spring_insight' describe JavaBuildpack::Framework::SpringInsight do - include_context 'component_helper' - include_context 'internet_availability_helper' + include_context 'with component help' + include_context 'with internet availability help' it 'does not detect without spring-insight-n/a service' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/framework/takipi_agent_spec.rb b/spec/java_buildpack/framework/takipi_agent_spec.rb index 333b9405df..83e7998d2e 100644 --- a/spec/java_buildpack/framework/takipi_agent_spec.rb +++ b/spec/java_buildpack/framework/takipi_agent_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/takipi_agent' describe JavaBuildpack::Framework::TakipiAgent do - include_context 'component_helper' + include_context 'with component help' let(:configuration) { { 'node_name_prefix' => nil } } @@ -65,7 +65,7 @@ expect(environment_variables).to include('TAKIPI_MASTER_HOST=test-host') end - context 'secret key' do + context 'with secret key' do let(:credentials) { super().merge 'secret_key' => 'test-key' } it 'secret key set' do @@ -75,7 +75,7 @@ end end - context 'configuration overrides' do + context 'with configuration overrides' do let(:configuration) { { 'node_name_prefix' => 'test-name', 'application_name' => 'test-name' } } diff --git a/spec/java_buildpack/framework/your_kit_profiler_spec.rb b/spec/java_buildpack/framework/your_kit_profiler_spec.rb index 55c63d5382..42968b82ec 100644 --- a/spec/java_buildpack/framework/your_kit_profiler_spec.rb +++ b/spec/java_buildpack/framework/your_kit_profiler_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/framework/your_kit_profiler' describe JavaBuildpack::Framework::YourKitProfiler do - include_context 'component_helper' + include_context 'with component help' it 'does not detect if not enabled' do expect(component.detect).to be_nil diff --git a/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb b/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb index 689db1106e..e8377d05cc 100644 --- a/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/jre/ibm_jre_initializer' describe JavaBuildpack::Jre::IbmJreInitializer do - include_context 'component_helper' + include_context 'with component help' let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } diff --git a/spec/java_buildpack/jre/ibm_jre_spec.rb b/spec/java_buildpack/jre/ibm_jre_spec.rb index ae8a77602c..efd7c730af 100644 --- a/spec/java_buildpack/jre/ibm_jre_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_spec.rb @@ -21,7 +21,7 @@ require 'java_buildpack/jre/ibm_jre' describe JavaBuildpack::Jre::IbmJRE do - include_context 'component_helper' + include_context 'with component help' let(:component) { StubIbmJRE.new context } diff --git a/spec/java_buildpack/jre/jvmkill_agent_spec.rb b/spec/java_buildpack/jre/jvmkill_agent_spec.rb index 762cafb7d9..0b0f2f7764 100644 --- a/spec/java_buildpack/jre/jvmkill_agent_spec.rb +++ b/spec/java_buildpack/jre/jvmkill_agent_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/jre/jvmkill_agent' describe JavaBuildpack::Jre::JvmkillAgent do - include_context 'component_helper' + include_context 'with component help' it 'copies executable to bin directory', cache_fixture: 'stub-jvmkill-agent' do diff --git a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index dba74a01d8..d04858bc63 100644 --- a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -20,7 +20,7 @@ require 'resolv' describe JavaBuildpack::Jre::OpenJDKLikeJre do - include_context 'component_helper' + include_context 'with component help' let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 200aa7014a..3acaf5718b 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -20,7 +20,7 @@ require 'java_buildpack/util/qualify_path' describe JavaBuildpack::Jre::OpenJDKLikeMemoryCalculator do - include_context 'component_helper' + include_context 'with component help' include JavaBuildpack::Util let(:configuration) { { 'stack_threads' => '200' } } diff --git a/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb b/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb index 277bef1a80..1dbab5b413 100644 --- a/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/jre/open_jdk_like_security_providers' describe JavaBuildpack::Jre::OpenJDKLikeSecurityProviders do - include_context 'component_helper' + include_context 'with component help' it 'does not add extension directories with no JRE default' do component.release diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index 399b50cf6a..fc7cd720e7 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -23,7 +23,7 @@ require 'java_buildpack/jre/open_jdk_like_security_providers' describe JavaBuildpack::Jre::OpenJDKLike do - include_context 'component_helper' + include_context 'with component help' let(:component) { StubOpenJDKLike.new context } diff --git a/spec/java_buildpack/logging/delegating_logger_spec.rb b/spec/java_buildpack/logging/delegating_logger_spec.rb index 73488f228c..ba789d0547 100644 --- a/spec/java_buildpack/logging/delegating_logger_spec.rb +++ b/spec/java_buildpack/logging/delegating_logger_spec.rb @@ -19,7 +19,7 @@ describe JavaBuildpack::Logging::DelegatingLogger do - let(:block) { ->() { 'test-message' } } + let(:block) { -> { 'test-message' } } let(:delegate1) { instance_double('delegate1') } let(:delegate2) { instance_double('delegate2') } let(:delegating_logger) { described_class.new('test-klass', [delegate1, delegate2]) } diff --git a/spec/java_buildpack/logging/logger_factory_spec.rb b/spec/java_buildpack/logging/logger_factory_spec.rb index 6fa3ebe54a..f3f9bd86bf 100644 --- a/spec/java_buildpack/logging/logger_factory_spec.rb +++ b/spec/java_buildpack/logging/logger_factory_spec.rb @@ -20,8 +20,8 @@ require 'java_buildpack/util/configuration_utils' describe JavaBuildpack::Logging::LoggerFactory do - include_context 'console_helper' - include_context 'logging_helper' + include_context 'with console help' + include_context 'with logging help' let(:logger) { described_class.instance.get_logger String } diff --git a/spec/java_buildpack/repository/repository_index_spec.rb b/spec/java_buildpack/repository/repository_index_spec.rb index e66d782e38..39f52a3f10 100644 --- a/spec/java_buildpack/repository/repository_index_spec.rb +++ b/spec/java_buildpack/repository/repository_index_spec.rb @@ -24,8 +24,8 @@ require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Repository::RepositoryIndex do - include_context 'application_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with logging help' let(:application_cache) { instance_double('ApplicationCache') } diff --git a/spec/java_buildpack/repository/version_resolver_spec.rb b/spec/java_buildpack/repository/version_resolver_spec.rb index afd62bf17a..59cbb11a27 100644 --- a/spec/java_buildpack/repository/version_resolver_spec.rb +++ b/spec/java_buildpack/repository/version_resolver_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Repository::VersionResolver do - include_context 'logging_helper' + include_context 'with logging help' let(:versions) do %w[1.6.0_26 1.6.0_27 1.6.0_112 1.6.0_102 1.6.0_45RELEASE 1.6.1_14 1.7.0_19 1.7.0_21 1.8.0_M-7 1.8.0_05 2.0.0 2.0.0a] diff --git a/spec/java_buildpack/util/cache/application_cache_spec.rb b/spec/java_buildpack/util/cache/application_cache_spec.rb index b8815a4432..bd28d1cc9e 100644 --- a/spec/java_buildpack/util/cache/application_cache_spec.rb +++ b/spec/java_buildpack/util/cache/application_cache_spec.rb @@ -20,9 +20,9 @@ require 'java_buildpack/util/cache/application_cache' describe JavaBuildpack::Util::Cache::ApplicationCache do - include_context 'application_helper' - include_context 'internet_availability_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with internet availability help' + include_context 'with logging help' previous_arg_value = ARGV[1] @@ -50,7 +50,7 @@ it 'uses ARGV[1] directory' do ARGV[1] = app_dir - described_class.new.get('http://foo-uri/') {} + described_class.new.get('http://foo-uri/'){} expect(Pathname.glob(app_dir + '*.cached').size).to eq(1) end diff --git a/spec/java_buildpack/util/cache/cache_factory_spec.rb b/spec/java_buildpack/util/cache/cache_factory_spec.rb index aa554466d0..3ac294134e 100644 --- a/spec/java_buildpack/util/cache/cache_factory_spec.rb +++ b/spec/java_buildpack/util/cache/cache_factory_spec.rb @@ -22,9 +22,9 @@ require 'java_buildpack/util/cache/download_cache' describe JavaBuildpack::Util::Cache::CacheFactory do - include_context 'application_helper' - include_context 'internet_availability_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with internet availability help' + include_context 'with logging help' previous_arg_value = ARGV[1] diff --git a/spec/java_buildpack/util/cache/cached_file_spec.rb b/spec/java_buildpack/util/cache/cached_file_spec.rb index 097d7975e0..ea1460e4ca 100644 --- a/spec/java_buildpack/util/cache/cached_file_spec.rb +++ b/spec/java_buildpack/util/cache/cached_file_spec.rb @@ -20,7 +20,7 @@ require 'java_buildpack/util/cache/cached_file' describe JavaBuildpack::Util::Cache::CachedFile do - include_context 'application_helper' + include_context 'with application help' let(:cache_root) { app_dir + 'cache/root' } diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 687bf3b032..8a903dafdb 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -23,9 +23,9 @@ require 'net/http' describe JavaBuildpack::Util::Cache::DownloadCache do - include_context 'application_helper' - include_context 'internet_availability_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with internet availability help' + include_context 'with logging help' let(:ca_certs_directory) { instance_double('Pathname', exist?: false, to_s: 'test-path') } @@ -199,7 +199,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:Proxy).with('proxy', 9000, nil, nil).and_call_original - download_cache.get(uri) {} + download_cache.get(uri){} end end @@ -216,7 +216,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:Proxy).with('proxy', 9000, nil, nil).and_call_original - download_cache.get(uri) {} + download_cache.get(uri){} end end @@ -233,7 +233,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:Proxy).with('proxy', 9000, nil, nil).and_call_original - download_cache.get(uri_secure) {} + download_cache.get(uri_secure){} end end @@ -250,7 +250,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:Proxy).with('proxy', 9000, nil, nil).and_call_original - download_cache.get(uri_secure) {} + download_cache.get(uri_secure){} end end @@ -266,7 +266,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original expect(Net::HTTP).not_to have_received(:Proxy).with('proxy', 9000, nil, nil) - download_cache.get(uri_secure) {} + download_cache.get(uri_secure){} end end @@ -282,7 +282,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original expect(Net::HTTP).not_to have_received(:Proxy).with('proxy', 9000, nil, nil) - download_cache.get(uri_secure) {} + download_cache.get(uri_secure){} end end @@ -294,7 +294,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original - download_cache.get(uri) {} + download_cache.get(uri){} end it 'does not use ca_file if the URL is not secure and directory does exist' do @@ -305,7 +305,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original - download_cache.get(uri) {} + download_cache.get(uri){} end it 'does not use ca_file if the URL is secure and directory does not exist' do @@ -315,7 +315,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:start).with('foo-uri', 443, use_ssl: true).and_call_original - download_cache.get(uri_secure) {} + download_cache.get(uri_secure){} end it 'uses ca_file if the URL is secure and directory does exist' do @@ -326,7 +326,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:start).with('foo-uri', 443, use_ssl: true, ca_file: 'test-path').and_call_original - download_cache.get(uri_secure) {} + download_cache.get(uri_secure){} end it 'deletes the cached file if it exists' do diff --git a/spec/java_buildpack/util/cache/internet_availability_spec.rb b/spec/java_buildpack/util/cache/internet_availability_spec.rb index 09a379b2e6..3796d07d24 100644 --- a/spec/java_buildpack/util/cache/internet_availability_spec.rb +++ b/spec/java_buildpack/util/cache/internet_availability_spec.rb @@ -20,8 +20,8 @@ require 'java_buildpack/util/cache/internet_availability' describe JavaBuildpack::Util::Cache::InternetAvailability do - include_context 'internet_availability_helper' - include_context 'logging_helper' + include_context 'with internet availability help' + include_context 'with logging help' it 'uses internet by default' do expect(described_class.instance.available?).to be diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index d81790049a..97381e67e4 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -22,7 +22,7 @@ require 'yaml' describe JavaBuildpack::Util::ConfigurationUtils do - include_context 'logging_helper' + include_context 'with logging help' let(:test_data) do { 'foo' => { 'one' => '1', 'two' => 2 }, diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index 10c8d622e8..5a166685b5 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' describe JavaBuildpack::Util::FilteringPathname do - include_context 'application_helper' + include_context 'with application help' let(:filter_none) { ->(_) { true } } let(:filter_all) { ->(_) { false } } diff --git a/spec/java_buildpack/util/java_main_utils_spec.rb b/spec/java_buildpack/util/java_main_utils_spec.rb index 53d17b4e66..1453d692ed 100644 --- a/spec/java_buildpack/util/java_main_utils_spec.rb +++ b/spec/java_buildpack/util/java_main_utils_spec.rb @@ -20,8 +20,8 @@ require 'java_buildpack/util/java_main_utils' describe JavaBuildpack::Util::JavaMainUtils do - include_context 'application_helper' - include_context 'logging_helper' + include_context 'with application help' + include_context 'with logging help' let(:test_class_name) { 'test-java-main-class' } diff --git a/spec/java_buildpack/util/play/base_spec.rb b/spec/java_buildpack/util/play/base_spec.rb index 04ce456749..a11e2e00ca 100644 --- a/spec/java_buildpack/util/play/base_spec.rb +++ b/spec/java_buildpack/util/play/base_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/util/play/base' describe JavaBuildpack::Util::Play::Base do - include_context 'droplet_helper' + include_context 'with droplet help' let(:play) { described_class.new(droplet) } diff --git a/spec/java_buildpack/util/play/factory_spec.rb b/spec/java_buildpack/util/play/factory_spec.rb index db9c537fd0..cef4838c4b 100644 --- a/spec/java_buildpack/util/play/factory_spec.rb +++ b/spec/java_buildpack/util/play/factory_spec.rb @@ -19,8 +19,8 @@ require 'java_buildpack/util/play/factory' describe JavaBuildpack::Util::Play::Factory do - include_context 'console_helper' - include_context 'droplet_helper' + include_context 'with console help' + include_context 'with droplet help' let(:trigger) { described_class.create(droplet) } diff --git a/spec/java_buildpack/util/play/post22_dist_spec.rb b/spec/java_buildpack/util/play/post22_dist_spec.rb index 153ff08849..dc834bc293 100644 --- a/spec/java_buildpack/util/play/post22_dist_spec.rb +++ b/spec/java_buildpack/util/play/post22_dist_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/util/play/post22_dist' describe JavaBuildpack::Util::Play::Post22Dist do - include_context 'component_helper' + include_context 'with component help' context do diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index 895965a64d..58a1cecb2d 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -19,7 +19,7 @@ require 'java_buildpack/util/play/post22' describe JavaBuildpack::Util::Play::Post22 do - include_context 'component_helper' + include_context 'with component help' let(:play_app) { described_class.new(droplet) } diff --git a/spec/java_buildpack/util/play/post22_staged_spec.rb b/spec/java_buildpack/util/play/post22_staged_spec.rb index 6746b2e2ca..a7f362be73 100644 --- a/spec/java_buildpack/util/play/post22_staged_spec.rb +++ b/spec/java_buildpack/util/play/post22_staged_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/util/play/post22_staged' describe JavaBuildpack::Util::Play::Post22Staged do - include_context 'component_helper' + include_context 'with component help' context do diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index 22494c3c57..aaf98a9228 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/util/play/pre22_dist' describe JavaBuildpack::Util::Play::Pre22Dist do - include_context 'component_helper' + include_context 'with component help' context do diff --git a/spec/java_buildpack/util/play/pre22_spec.rb b/spec/java_buildpack/util/play/pre22_spec.rb index 12fe045d83..576ac000bc 100644 --- a/spec/java_buildpack/util/play/pre22_spec.rb +++ b/spec/java_buildpack/util/play/pre22_spec.rb @@ -19,8 +19,8 @@ require 'java_buildpack/util/play/pre22' describe JavaBuildpack::Util::Play::Pre22 do - include_context 'application_helper' - include_context 'droplet_helper' + include_context 'with application help' + include_context 'with droplet help' let(:play_app) { described_class.new(droplet) } diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index e7454e65ac..de5b67b57e 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/util/play/pre22_staged' describe JavaBuildpack::Util::Play::Pre22Staged do - include_context 'component_helper' + include_context 'with component help' context do diff --git a/spec/java_buildpack/util/ratpack_utils_spec.rb b/spec/java_buildpack/util/ratpack_utils_spec.rb index 1c7304d74d..73c89d23d7 100644 --- a/spec/java_buildpack/util/ratpack_utils_spec.rb +++ b/spec/java_buildpack/util/ratpack_utils_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/util/ratpack_utils' describe JavaBuildpack::Util::RatpackUtils do - include_context 'application_helper' + include_context 'with application help' let(:utils) { described_class.new } diff --git a/spec/java_buildpack/util/sanitize_spec.rb b/spec/java_buildpack/util/sanitize_spec.rb index 1afec26699..11770bd838 100644 --- a/spec/java_buildpack/util/sanitize_spec.rb +++ b/spec/java_buildpack/util/sanitize_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/util/sanitizer' describe 'sanitize_uri' do # rubocop:disable RSpec/DescribeClass - include_context 'application_helper' + include_context 'with application help' it 'sanitizes uri with credentials in' do expect('https://myuser:mypass@myhost/path/to/file'.sanitize_uri).to eq('https://myhost/path/to/file') diff --git a/spec/java_buildpack/util/shell_spec.rb b/spec/java_buildpack/util/shell_spec.rb index 5316544c07..3caefc0ffd 100644 --- a/spec/java_buildpack/util/shell_spec.rb +++ b/spec/java_buildpack/util/shell_spec.rb @@ -20,7 +20,7 @@ describe JavaBuildpack::Util::Shell do include described_class - include_context 'console_helper' + include_context 'with console help' it 'returns if command returns a zero exit code' do shell 'true' diff --git a/spec/java_buildpack/util/spring_boot_utils_spec.rb b/spec/java_buildpack/util/spring_boot_utils_spec.rb index 8911cfc33b..c64e20b2c7 100644 --- a/spec/java_buildpack/util/spring_boot_utils_spec.rb +++ b/spec/java_buildpack/util/spring_boot_utils_spec.rb @@ -18,7 +18,7 @@ require 'java_buildpack/util/spring_boot_utils' describe JavaBuildpack::Util::SpringBootUtils do - include_context 'droplet_helper' + include_context 'with droplet help' let(:utils) { described_class.new } diff --git a/spec/logging_helper.rb b/spec/logging_helper.rb index cde1815ff1..9ea15eaf41 100644 --- a/spec/logging_helper.rb +++ b/spec/logging_helper.rb @@ -20,9 +20,9 @@ require 'java_buildpack/logging/logger_factory' require 'yaml' -shared_context 'logging_helper' do - include_context 'console_helper' - include_context 'application_helper' +shared_context 'with logging help' do + include_context 'with console help' + include_context 'with application help' previous_log_config = ENV['JBP_CONFIG_LOGGING'] previous_log_level = ENV['JBP_LOG_LEVEL'] diff --git a/spec/memory_limit_helper.rb b/spec/memory_limit_helper.rb index 687537b083..a32bb74afe 100644 --- a/spec/memory_limit_helper.rb +++ b/spec/memory_limit_helper.rb @@ -15,7 +15,7 @@ require 'spec_helper' -shared_context 'memory_limit_helper' do +shared_context 'with memory limit help' do previous_memory_limit = ENV['MEMORY_LIMIT'] From 77478f81462ba49075db6c126c953ecfece83113 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 22 Dec 2017 10:15:00 -0800 Subject: [PATCH 389/812] Ruby Version Updates --- ci/docker-image/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 2acd25e0fb..4486424ef2 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -30,10 +30,10 @@ RUN eval "$(rbenv init -)" \ && echo 'bundler' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ - && rbenv install 2.2.8 + && rbenv install 2.2.9 RUN eval "$(rbenv init -)" \ - && rbenv install 2.3.5 + && rbenv install 2.3.6 RUN eval "$(rbenv init -)" \ - && rbenv install 2.4.2 + && rbenv install 2.4.3 From 9f97630dcf3c98e31b0efd41b53bec4455fd63ec Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 22 Dec 2017 10:15:27 -0800 Subject: [PATCH 390/812] Default Ruby Version Update --- .idea/misc.xml | 2 +- .ruby-version | 2 +- java-buildpack.iml | 58 +++++++++++++++++++++++----------------------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index acd064c15c..f04bcecaa8 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,5 +4,5 @@ - + \ No newline at end of file diff --git a/.ruby-version b/.ruby-version index 23a63f524e..a6333e4006 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.2.8 +2.2.9 diff --git a/java-buildpack.iml b/java-buildpack.iml index a9b05c4a98..cef16bdd8e 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -265,36 +265,36 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b32489f5f85354934ba43d115aee6a8a19047f7c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 17 Jan 2018 10:39:49 -0800 Subject: [PATCH 391/812] Polishing --- .idea/runConfigurations/All_Tests__2_2_.xml | 2 +- .idea/runConfigurations/All_Tests__2_3_.xml | 2 +- .idea/runConfigurations/All_Tests__2_4_.xml | 2 +- .idea/runConfigurations/Without_Integration_Tests__2_2_.xml | 2 +- .idea/runConfigurations/Without_Integration_Tests__2_3_.xml | 2 +- .idea/runConfigurations/Without_Integration_Tests__2_4_.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.idea/runConfigurations/All_Tests__2_2_.xml b/.idea/runConfigurations/All_Tests__2_2_.xml index d268e3da49..6383884ac7 100644 --- a/.idea/runConfigurations/All_Tests__2_2_.xml +++ b/.idea/runConfigurations/All_Tests__2_2_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_3_.xml b/.idea/runConfigurations/All_Tests__2_3_.xml index b5f8fc31ff..92c132a81e 100644 --- a/.idea/runConfigurations/All_Tests__2_3_.xml +++ b/.idea/runConfigurations/All_Tests__2_3_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_4_.xml b/.idea/runConfigurations/All_Tests__2_4_.xml index a28ec423a3..3695657f1a 100644 --- a/.idea/runConfigurations/All_Tests__2_4_.xml +++ b/.idea/runConfigurations/All_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml index b24c428bcf..e69835c582 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml index 2332d91353..a20038c22a 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml index 6e2a813de3..cad6c77106 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + From e20b9bd147abaa2e93edb5e597d6e057c6b64b76 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 17 Jan 2018 11:27:36 -0800 Subject: [PATCH 392/812] Drop Ruby 2.2, Add Ruby 2.5 This change drops Ruby 2.2.x as Ruby 2.3.x is now the oldest supported Ruby. This change also add Ruby 2.5.x to ensure that we're ready to go when that shows up in CF stemcells. --- .idea/misc.xml | 2 +- ...ll_Tests__2_2_.xml => All_Tests__2_5_.xml} | 4 +- ...ml => Without_Integration_Tests__2_5_.xml} | 4 +- .rubocop.yml | 2 - .ruby-version | 2 +- Gemfile.lock | 12 +-- Rakefile | 2 + bin/compile | 2 + bin/detect | 2 + bin/finalize | 2 + bin/release | 2 + ci/docker-image/Dockerfile | 6 +- java-buildpack.iml | 58 ++++++------ lib/java_buildpack.rb | 2 + lib/java_buildpack/buildpack.rb | 4 +- lib/java_buildpack/buildpack_version.rb | 2 + lib/java_buildpack/component.rb | 2 + .../component/additional_libraries.rb | 2 + lib/java_buildpack/component/application.rb | 2 + .../component/base_component.rb | 2 + lib/java_buildpack/component/droplet.rb | 2 + .../component/environment_variables.rb | 2 + .../component/extension_directories.rb | 2 + .../component/immutable_java_home.rb | 2 + lib/java_buildpack/component/java_opts.rb | 2 + .../component/modular_component.rb | 2 + .../component/mutable_java_home.rb | 2 + lib/java_buildpack/component/networking.rb | 2 + .../component/security_providers.rb | 2 + lib/java_buildpack/component/services.rb | 2 + .../versioned_dependency_component.rb | 2 + lib/java_buildpack/container.rb | 2 + lib/java_buildpack/container/dist_zip.rb | 9 +- lib/java_buildpack/container/dist_zip_like.rb | 2 + lib/java_buildpack/container/groovy.rb | 2 + lib/java_buildpack/container/java_main.rb | 6 +- .../container/play_framework.rb | 6 +- lib/java_buildpack/container/ratpack.rb | 4 +- lib/java_buildpack/container/spring_boot.rb | 4 +- .../container/spring_boot_cli.rb | 2 + lib/java_buildpack/container/tomcat.rb | 2 + .../tomcat/tomcat_access_logging_support.rb | 4 +- .../tomcat/tomcat_external_configuration.rb | 2 + .../container/tomcat/tomcat_geode_store.rb | 18 ++-- .../tomcat/tomcat_insight_support.rb | 2 + .../container/tomcat/tomcat_instance.rb | 2 + .../tomcat/tomcat_lifecycle_support.rb | 2 + .../tomcat/tomcat_logging_support.rb | 2 + .../container/tomcat/tomcat_redis_store.rb | 16 ++-- .../container/tomcat/tomcat_utils.rb | 2 + lib/java_buildpack/framework.rb | 2 + .../framework/app_dynamics_agent.rb | 2 + .../framework/aspectj_weaver_agent.rb | 2 + .../framework/client_certificate_mapper.rb | 2 + .../framework/container_customizer.rb | 2 + .../framework/container_security_provider.rb | 2 + .../framework/contrast_security_agent.rb | 14 +-- lib/java_buildpack/framework/debug.rb | 2 + .../framework/dyadic_ekm_security_provider.rb | 14 +-- .../framework/dynatrace_appmon_agent.rb | 2 + .../framework/dynatrace_one_agent.rb | 20 ++-- .../framework/google_stackdriver_debugger.rb | 4 +- .../framework/introscope_agent.rb | 2 + .../framework/java_memory_assistant.rb | 2 + .../framework/java_memory_assistant/agent.rb | 2 + .../java_memory_assistant/clean_up.rb | 4 +- .../java_memory_assistant/heap_dump_folder.rb | 4 +- lib/java_buildpack/framework/java_opts.rb | 6 +- lib/java_buildpack/framework/java_security.rb | 2 + lib/java_buildpack/framework/jmx.rb | 2 + lib/java_buildpack/framework/jrebel_agent.rb | 2 + .../framework/luna_security_provider.rb | 94 ++++++++++--------- lib/java_buildpack/framework/maria_db_jdbc.rb | 2 + lib/java_buildpack/framework/metric_writer.rb | 6 +- .../framework/multi_buildpack.rb | 2 + .../framework/new_relic_agent.rb | 6 +- .../framework/postgresql_jdbc.rb | 2 + .../protect_app_security_provider.rb | 2 + .../framework/spring_auto_reconfiguration.rb | 2 + .../framework/spring_insight.rb | 2 + lib/java_buildpack/framework/takipi_agent.rb | 6 +- .../framework/your_kit_profiler.rb | 2 + lib/java_buildpack/jre.rb | 2 + lib/java_buildpack/jre/ibm_jre.rb | 2 + lib/java_buildpack/jre/ibm_jre_initializer.rb | 4 +- lib/java_buildpack/jre/jvmkill_agent.rb | 2 + lib/java_buildpack/jre/open_jdk_jre.rb | 2 + lib/java_buildpack/jre/open_jdk_like.rb | 2 + lib/java_buildpack/jre/open_jdk_like_jre.rb | 2 + .../jre/open_jdk_like_memory_calculator.rb | 2 + .../jre/open_jdk_like_security_providers.rb | 8 +- lib/java_buildpack/jre/oracle_jre.rb | 2 + lib/java_buildpack/jre/zulu_jre.rb | 2 + lib/java_buildpack/logging.rb | 2 + .../logging/delegating_logger.rb | 2 + lib/java_buildpack/logging/logger_factory.rb | 2 + lib/java_buildpack/repository.rb | 2 + .../repository/configured_item.rb | 6 +- .../repository/repository_index.rb | 4 +- .../repository/version_resolver.rb | 2 + lib/java_buildpack/util.rb | 2 + lib/java_buildpack/util/cache.rb | 2 + .../util/cache/application_cache.rb | 2 + .../util/cache/cache_factory.rb | 2 + lib/java_buildpack/util/cache/cached_file.rb | 2 + .../util/cache/download_cache.rb | 2 + .../util/cache/inferred_network_failure.rb | 2 + .../util/cache/internet_availability.rb | 2 + lib/java_buildpack/util/class_file_utils.rb | 4 +- lib/java_buildpack/util/colorize.rb | 2 + .../util/configuration_utils.rb | 4 +- lib/java_buildpack/util/constantize.rb | 2 + lib/java_buildpack/util/dash_case.rb | 2 + lib/java_buildpack/util/file_enumerable.rb | 2 + lib/java_buildpack/util/filtering_pathname.rb | 2 + .../util/find_single_directory.rb | 2 + lib/java_buildpack/util/format_duration.rb | 6 +- lib/java_buildpack/util/groovy_utils.rb | 4 +- lib/java_buildpack/util/jar_finder.rb | 2 + lib/java_buildpack/util/java_main_utils.rb | 6 +- lib/java_buildpack/util/play.rb | 2 + lib/java_buildpack/util/play/base.rb | 8 +- lib/java_buildpack/util/play/factory.rb | 2 + lib/java_buildpack/util/play/post22.rb | 2 + lib/java_buildpack/util/play/post22_dist.rb | 2 + lib/java_buildpack/util/play/post22_staged.rb | 2 + lib/java_buildpack/util/play/pre22.rb | 2 + lib/java_buildpack/util/play/pre22_dist.rb | 2 + lib/java_buildpack/util/play/pre22_staged.rb | 2 + lib/java_buildpack/util/properties.rb | 2 + lib/java_buildpack/util/qualify_path.rb | 2 + lib/java_buildpack/util/ratpack_utils.rb | 2 + lib/java_buildpack/util/sanitizer.rb | 2 + lib/java_buildpack/util/shell.rb | 2 + lib/java_buildpack/util/snake_case.rb | 2 + lib/java_buildpack/util/space_case.rb | 2 + lib/java_buildpack/util/spring_boot_utils.rb | 14 +-- lib/java_buildpack/util/start_script.rb | 2 + lib/java_buildpack/util/to_b.rb | 2 + lib/java_buildpack/util/tokenized_version.rb | 4 +- rakelib/dependency_cache_task.rb | 4 +- rakelib/package.rb | 8 +- rakelib/package_task.rb | 2 + rakelib/stage_buildpack_task.rb | 2 + rakelib/versions_task.rb | 2 + spec/application_helper.rb | 2 + spec/bin/compile_spec.rb | 2 + spec/bin/detect_spec.rb | 2 + spec/bin/release_spec.rb | 2 + spec/component_helper.rb | 4 +- spec/console_helper.rb | 2 + spec/droplet_helper.rb | 2 + .../Chrystoki.conf | 4 +- .../container/long_detect_tags.rb | 2 + spec/integration_helper.rb | 2 + spec/internet_availability_helper.rb | 2 + spec/java_buildpack/buildpack_spec.rb | 2 + spec/java_buildpack/buildpack_version_spec.rb | 2 + .../component/additional_libraries_spec.rb | 2 + .../component/application_spec.rb | 2 + .../component/base_component_spec.rb | 2 + spec/java_buildpack/component/droplet_spec.rb | 2 + .../component/environment_variables_spec.rb | 2 + .../component/extension_directories_spec.rb | 2 + .../component/immutable_java_home_spec.rb | 2 + .../component/java_opts_spec.rb | 2 + .../component/modular_component_spec.rb | 2 + .../component/mutable_java_home_spec.rb | 2 + .../component/security_providers_spec.rb | 2 + .../java_buildpack/component/services_spec.rb | 2 + .../versioned_dependency_component_spec.rb | 2 + .../container/dist_zip_like_spec.rb | 2 + .../java_buildpack/container/dist_zip_spec.rb | 2 + spec/java_buildpack/container/groovy_spec.rb | 2 + .../container/java_main_spec.rb | 2 + .../container/play_framework_spec.rb | 2 + spec/java_buildpack/container/ratpack_spec.rb | 2 + .../container/spring_boot_cli_spec.rb | 2 + .../container/spring_boot_spec.rb | 2 + .../tomcat_access_logging_support_spec.rb | 2 + .../tomcat_external_configuration_spec.rb | 2 + .../tomcat/tomcat_geode_store_spec.rb | 2 + .../tomcat/tomcat_insight_support_spec.rb | 2 + .../container/tomcat/tomcat_instance_spec.rb | 2 + .../tomcat/tomcat_lifecycle_support_spec.rb | 2 + .../tomcat/tomcat_logging_support_spec.rb | 2 + .../tomcat/tomcat_redis_store_spec.rb | 2 + spec/java_buildpack/container/tomcat_spec.rb | 2 + .../framework/app_dynamics_agent_spec.rb | 2 + .../framework/aspectj_weaver_agent_spec.rb | 2 + .../client_certificate_mapper_spec.rb | 2 + .../framework/container_customizer_spec.rb | 2 + .../container_security_provider_spec.rb | 2 + .../framework/contrast_security_agent_spec.rb | 6 +- spec/java_buildpack/framework/debug_spec.rb | 2 + .../dyadic_ekm_security_provider_spec.rb | 2 + .../framework/dynatrace_appmon_agent_spec.rb | 2 + .../framework/dynatrace_one_agent_spec.rb | 2 + .../google_stackdriver_debugger_spec.rb | 2 + .../framework/introscope_agent_spec.rb | 2 + .../java_memory_assistant/agent_spec.rb | 2 + .../java_memory_assistant/clean_up_spec.rb | 2 + .../heap_dump_folder_spec.rb | 2 + .../framework/java_memory_assistant_spec.rb | 2 + .../framework/java_opts_spec.rb | 2 + .../framework/java_security_spec.rb | 2 + spec/java_buildpack/framework/jmx_spec.rb | 2 + .../framework/jrebel_agent_spec.rb | 2 + .../framework/luna_security_provider_spec.rb | 2 + .../framework/maria_db_jdbc_spec.rb | 2 + .../framework/metric_writer_spec.rb | 2 + .../framework/multi_buildpack_spec.rb | 2 + .../framework/new_relic_agent_spec.rb | 2 + .../framework/postgresql_jdbc_spec.rb | 2 + .../protect_app_security_provider_spec.rb | 2 + .../spring_auto_reconfiguration_spec.rb | 2 + .../framework/spring_insight_spec.rb | 2 + .../framework/takipi_agent_spec.rb | 2 + .../framework/your_kit_profiler_spec.rb | 2 + .../jre/ibm_jre_initializer_spec.rb | 2 + spec/java_buildpack/jre/ibm_jre_spec.rb | 2 + spec/java_buildpack/jre/jvmkill_agent_spec.rb | 2 + .../jre/open_jdk_like_jre_spec.rb | 2 + .../open_jdk_like_memory_calculator_spec.rb | 2 + .../open_jdk_like_security_providers_spec.rb | 2 + spec/java_buildpack/jre/open_jdk_like_spec.rb | 2 + .../logging/delegating_logger_spec.rb | 2 + .../logging/logger_factory_spec.rb | 2 + .../repository/configured_item_spec.rb | 2 + .../repository/repository_index_spec.rb | 2 + .../repository/version_resolver_spec.rb | 2 + .../util/cache/application_cache_spec.rb | 4 +- .../util/cache/cache_factory_spec.rb | 2 + .../util/cache/cached_file_spec.rb | 2 + .../util/cache/download_cache_spec.rb | 22 +++-- .../util/cache/internet_availability_spec.rb | 2 + .../util/cache/yield_file_with_content.rb | 2 + .../util/configuration_utils_spec.rb | 2 + spec/java_buildpack/util/constantize_spec.rb | 2 + .../util/filtering_pathname_spec.rb | 2 + .../util/format_duration_spec.rb | 2 + .../util/java_main_utils_spec.rb | 2 + spec/java_buildpack/util/play/base_spec.rb | 2 + spec/java_buildpack/util/play/factory_spec.rb | 2 + .../util/play/post22_dist_spec.rb | 2 + spec/java_buildpack/util/play/post22_spec.rb | 2 + .../util/play/post22_staged_spec.rb | 2 + .../util/play/pre22_dist_spec.rb | 2 + spec/java_buildpack/util/play/pre22_spec.rb | 2 + .../util/play/pre22_staged_spec.rb | 2 + spec/java_buildpack/util/properties_spec.rb | 2 + .../java_buildpack/util/ratpack_utils_spec.rb | 2 + spec/java_buildpack/util/sanitize_spec.rb | 2 + spec/java_buildpack/util/shell_spec.rb | 2 + .../util/spring_boot_utils_spec.rb | 2 + .../util/tokenized_version_spec.rb | 2 + spec/logging_helper.rb | 2 + spec/memory_limit_helper.rb | 2 + spec/spec_helper.rb | 2 + 259 files changed, 692 insertions(+), 195 deletions(-) rename .idea/runConfigurations/{All_Tests__2_2_.xml => All_Tests__2_5_.xml} (96%) rename .idea/runConfigurations/{Without_Integration_Tests__2_2_.xml => Without_Integration_Tests__2_5_.xml} (96%) diff --git a/.idea/misc.xml b/.idea/misc.xml index f04bcecaa8..dfe47e3d44 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,5 +4,5 @@ - + \ No newline at end of file diff --git a/.idea/runConfigurations/All_Tests__2_2_.xml b/.idea/runConfigurations/All_Tests__2_5_.xml similarity index 96% rename from .idea/runConfigurations/All_Tests__2_2_.xml rename to .idea/runConfigurations/All_Tests__2_5_.xml index 6383884ac7..e6f973adb7 100644 --- a/.idea/runConfigurations/All_Tests__2_2_.xml +++ b/.idea/runConfigurations/All_Tests__2_5_.xml @@ -1,11 +1,11 @@ - + - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml similarity index 96% rename from .idea/runConfigurations/Without_Integration_Tests__2_2_.xml rename to .idea/runConfigurations/Without_Integration_Tests__2_5_.xml index e69835c582..75a1a5cce2 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_2_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml @@ -1,11 +1,11 @@ - + - + diff --git a/.rubocop.yml b/.rubocop.yml index d099153199..a33fec8b44 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -15,8 +15,6 @@ Layout/EmptyLinesAroundClassBody: Enabled: false Layout/EmptyLinesAroundModuleBody: Enabled: false -Layout/IndentHeredoc: # TODO: Remove when dropping 2.2.x support - Enabled: false Layout/MultilineOperationIndentation: Enabled: false Metrics/AbcSize: diff --git a/.ruby-version b/.ruby-version index a6333e4006..e75da3e63d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.2.9 +2.3.6 diff --git a/Gemfile.lock b/Gemfile.lock index 7ec4ee399c..1a3fe387f8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,7 +20,7 @@ GEM rspec-core (~> 3.7.0) rspec-expectations (~> 3.7.0) rspec-mocks (~> 3.7.0) - rspec-core (3.7.0) + rspec-core (3.7.1) rspec-support (~> 3.7.0) rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) @@ -29,15 +29,15 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) rspec-support (3.7.0) - rubocop (0.52.0) + rubocop (0.52.1) parallel (~> 1.10) parser (>= 2.4.0.2, < 3.0) powerpack (~> 0.1) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.21.0) - rubocop (>= 0.52.0) + rubocop-rspec (1.22.1) + rubocop (>= 0.52.1) ruby-progressbar (1.9.0) rubyzip (1.2.1) safe_yaml (1.0.4) @@ -45,7 +45,7 @@ GEM terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) unicode-display_width (1.3.0) - webmock (3.1.1) + webmock (3.2.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff @@ -67,4 +67,4 @@ DEPENDENCIES yard BUNDLED WITH - 1.16.0 + 1.16.1 diff --git a/Rakefile b/Rakefile index 30855160a8..b99e8dc301 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/bin/compile b/bin/compile index c2c06cb28d..e80809942b 100755 --- a/bin/compile +++ b/bin/compile @@ -1,4 +1,6 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/bin/detect b/bin/detect index 54ef35f955..007359474c 100755 --- a/bin/detect +++ b/bin/detect @@ -1,4 +1,6 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/bin/finalize b/bin/finalize index 2b7c8300a3..8f31b62681 100755 --- a/bin/finalize +++ b/bin/finalize @@ -1,4 +1,6 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/bin/release b/bin/release index 02f9b07f6f..4a87978177 100755 --- a/bin/release +++ b/bin/release @@ -1,4 +1,6 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 4486424ef2..a6fbdd8f41 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -29,11 +29,11 @@ RUN eval "$(rbenv init -)" \ && git clone https://github.com/sstephenson/rbenv-default-gems.git $(rbenv root)/plugins/rbenv-default-gems \ && echo 'bundler' >> $(rbenv root)/default-gems -RUN eval "$(rbenv init -)" \ - && rbenv install 2.2.9 - RUN eval "$(rbenv init -)" \ && rbenv install 2.3.6 RUN eval "$(rbenv init -)" \ && rbenv install 2.4.3 + +RUN eval "$(rbenv init -)" \ + && rbenv install 2.5.0 diff --git a/java-buildpack.iml b/java-buildpack.iml index cef16bdd8e..c1dd94d3e9 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -265,36 +265,36 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/java_buildpack.rb b/lib/java_buildpack.rb index e74cba26c4..07acf3d074 100644 --- a/lib/java_buildpack.rb +++ b/lib/java_buildpack.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 850628dbc0..154c20ddf2 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -105,7 +107,7 @@ def release private - BUILDPACK_MESSAGE = "#{'----->'.red.bold} #{'Java Buildpack'.blue.bold} %s".freeze + BUILDPACK_MESSAGE = "#{'----->'.red.bold} #{'Java Buildpack'.blue.bold} %s" LOAD_ROOT = (Pathname.new(__FILE__).dirname + '..').freeze diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index 411e4b7327..d03c16b017 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component.rb b/lib/java_buildpack/component.rb index 8a409fcaff..c30d29afa5 100644 --- a/lib/java_buildpack/component.rb +++ b/lib/java_buildpack/component.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/additional_libraries.rb b/lib/java_buildpack/component/additional_libraries.rb index 5fd7159bb7..d8c9dcb0db 100644 --- a/lib/java_buildpack/component/additional_libraries.rb +++ b/lib/java_buildpack/component/additional_libraries.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index 8f1867eb03..5c0fac8b94 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 5c744f5c74..a6e8c000fb 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index db8f90a4b3..063520c765 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/environment_variables.rb b/lib/java_buildpack/component/environment_variables.rb index 9a1da704a1..bd5b69b0d9 100644 --- a/lib/java_buildpack/component/environment_variables.rb +++ b/lib/java_buildpack/component/environment_variables.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/extension_directories.rb b/lib/java_buildpack/component/extension_directories.rb index b27b832d72..f2dfdb5ddc 100644 --- a/lib/java_buildpack/component/extension_directories.rb +++ b/lib/java_buildpack/component/extension_directories.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index 1d2f10a315..f1fa94d8f3 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index ab85d586fc..748dd47746 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/modular_component.rb b/lib/java_buildpack/component/modular_component.rb index c738ee916a..bec963ce63 100644 --- a/lib/java_buildpack/component/modular_component.rb +++ b/lib/java_buildpack/component/modular_component.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index 1cd4cfd5bd..e546e1d5b3 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/networking.rb b/lib/java_buildpack/component/networking.rb index 7809ba3345..6422aff398 100644 --- a/lib/java_buildpack/component/networking.rb +++ b/lib/java_buildpack/component/networking.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/security_providers.rb b/lib/java_buildpack/component/security_providers.rb index 097f118ccf..89241a6051 100644 --- a/lib/java_buildpack/component/security_providers.rb +++ b/lib/java_buildpack/component/security_providers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/services.rb b/lib/java_buildpack/component/services.rb index 8c484d4cda..e08b167934 100644 --- a/lib/java_buildpack/component/services.rb +++ b/lib/java_buildpack/component/services.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/component/versioned_dependency_component.rb b/lib/java_buildpack/component/versioned_dependency_component.rb index 796043d991..3f8f4ce4f5 100644 --- a/lib/java_buildpack/component/versioned_dependency_component.rb +++ b/lib/java_buildpack/component/versioned_dependency_component.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container.rb b/lib/java_buildpack/container.rb index 9fc8136888..4b8a910a53 100644 --- a/lib/java_buildpack/container.rb +++ b/lib/java_buildpack/container.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/dist_zip.rb b/lib/java_buildpack/container/dist_zip.rb index 34546db5fa..b2d52fbc97 100644 --- a/lib/java_buildpack/container/dist_zip.rb +++ b/lib/java_buildpack/container/dist_zip.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -44,12 +46,11 @@ def id # (see JavaBuildpack::Container::DistZipLike#supports?) def supports? - start_script(root) && - start_script(root).exist? && + start_script(root)&.exist? && jars? && !@ratpack_utils.is?(@application) && - !@spring_boot_utils.is?(@application) && - !JavaBuildpack::Util::Play::Factory.create(@droplet) + !@spring_boot_utils.is?(@application) && + !JavaBuildpack::Util::Play::Factory.create(@droplet) end private diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index deb29d8a0a..e999f8a85e 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index dbb3147f9f..11392c3f3e 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index d036905af0..c4695d3274 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -64,9 +66,9 @@ def release private - ARGUMENTS_PROPERTY = 'arguments'.freeze + ARGUMENTS_PROPERTY = 'arguments' - CLASS_PATH_PROPERTY = 'Class-Path'.freeze + CLASS_PATH_PROPERTY = 'Class-Path' private_constant :ARGUMENTS_PROPERTY, :CLASS_PATH_PROPERTY diff --git a/lib/java_buildpack/container/play_framework.rb b/lib/java_buildpack/container/play_framework.rb index 4639b9d277..02cdb9fb6e 100644 --- a/lib/java_buildpack/container/play_framework.rb +++ b/lib/java_buildpack/container/play_framework.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -39,12 +41,12 @@ def detect # (see JavaBuildpack::Component::BaseComponent#compile) def compile - @delegate.compile if @delegate + @delegate&.compile end # (see JavaBuildpack::Component::BaseComponent#release) def release - @delegate.release if @delegate + @delegate&.release end private diff --git a/lib/java_buildpack/container/ratpack.rb b/lib/java_buildpack/container/ratpack.rb index 4ac829ca99..f5f00e2ff7 100644 --- a/lib/java_buildpack/container/ratpack.rb +++ b/lib/java_buildpack/container/ratpack.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -41,7 +43,7 @@ def id # (see JavaBuildpack::Container::DistZipLike#supports?) def supports? - start_script(root) && start_script(root).exist? && @ratpack_utils.is?(@application) + start_script(root)&.exist? && @ratpack_utils.is?(@application) end private diff --git a/lib/java_buildpack/container/spring_boot.rb b/lib/java_buildpack/container/spring_boot.rb index 074b13b4e8..154f14650e 100644 --- a/lib/java_buildpack/container/spring_boot.rb +++ b/lib/java_buildpack/container/spring_boot.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -47,7 +49,7 @@ def id # (see JavaBuildpack::Container::DistZipLike#supports?) def supports? - start_script(root) && start_script(root).exist? && @spring_boot_utils.is?(@application) + start_script(root)&.exist? && @spring_boot_utils.is?(@application) end private diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index cbc8a5487a..974858780e 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 24a5d7da02..47333a229a 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb index 94fe74a60c..22c29dd934 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -43,7 +45,7 @@ def supports? private - KEY_ENABLED = 'access_logging'.freeze + KEY_ENABLED = 'access_logging' def jar_name "tomcat_access_logging_support-#{@version}.jar" diff --git a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb index 8f33a1f7c7..e03c341ab2 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index a6cf494f75..cbb0c5cf14 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -56,16 +58,16 @@ def supports? private FILTER = /session-replication/ - KEY_LOCATORS = 'locators'.freeze - KEY_USERS = 'users'.freeze + KEY_LOCATORS = 'locators' + KEY_USERS = 'users' - SESSION_MANAGER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.Tomcat8DeltaSessionManager'.freeze - REGION_ATTRIBUTES_ID = 'PARTITION_REDUNDANT_HEAP_LRU'.freeze + SESSION_MANAGER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.Tomcat8DeltaSessionManager' + REGION_ATTRIBUTES_ID = 'PARTITION_REDUNDANT_HEAP_LRU' CACHE_CLIENT_LISTENER_CLASS_NAME = - 'org.apache.geode.modules.session.catalina.ClientServerCacheLifecycleListener'.freeze - SCHEMA_URL = 'http://geode.apache.org/schema/cache'.freeze - SCHEMA_INSTANCE_URL = 'http://www.w3.org/2001/XMLSchema-instance'.freeze - SCHEMA_LOCATION = 'http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd'.freeze + 'org.apache.geode.modules.session.catalina.ClientServerCacheLifecycleListener' + SCHEMA_URL = 'http://geode.apache.org/schema/cache' + SCHEMA_INSTANCE_URL = 'http://www.w3.org/2001/XMLSchema-instance' + SCHEMA_LOCATION = 'http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd' LOCATOR_REGEXP = Regexp.new('([^\\[]+)\\[([^\\]]+)\\]').freeze FUNCTION_SERVICE_CLASS_NAMES = [ 'org.apache.geode.modules.util.CreateRegionFunction', diff --git a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb index bae6e8c787..0ad2ab5a01 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index 1406f53a46..eb991cd4d3 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb index 156a64ed67..9812f1e8e9 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb index 393fb1d380..3d8f58015c 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb index 084d3f9493..d8720ee0b8 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -47,19 +49,19 @@ def supports? FILTER = /session-replication/ - FLUSH_VALVE_CLASS_NAME = 'com.gopivotal.manager.SessionFlushValve'.freeze + FLUSH_VALVE_CLASS_NAME = 'com.gopivotal.manager.SessionFlushValve' - KEY_HOST_NAME = 'hostname'.freeze + KEY_HOST_NAME = 'hostname' - KEY_HOST = 'host'.freeze + KEY_HOST = 'host' - KEY_PASSWORD = 'password'.freeze + KEY_PASSWORD = 'password' - KEY_PORT = 'port'.freeze + KEY_PORT = 'port' - PERSISTENT_MANAGER_CLASS_NAME = 'org.apache.catalina.session.PersistentManager'.freeze + PERSISTENT_MANAGER_CLASS_NAME = 'org.apache.catalina.session.PersistentManager' - REDIS_STORE_CLASS_NAME = 'com.gopivotal.manager.redis.RedisStore'.freeze + REDIS_STORE_CLASS_NAME = 'com.gopivotal.manager.redis.RedisStore' private_constant :FILTER, :FLUSH_VALVE_CLASS_NAME, :KEY_HOST_NAME, :KEY_PASSWORD, :KEY_PORT, :PERSISTENT_MANAGER_CLASS_NAME, :REDIS_STORE_CLASS_NAME diff --git a/lib/java_buildpack/container/tomcat/tomcat_utils.rb b/lib/java_buildpack/container/tomcat/tomcat_utils.rb index 732dd9aebc..17fa04a498 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_utils.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_utils.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework.rb b/lib/java_buildpack/framework.rb index 24cc162ef1..771bc4f5b8 100644 --- a/lib/java_buildpack/framework.rb +++ b/lib/java_buildpack/framework.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index b6b87595b4..ab23d85abe 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/aspectj_weaver_agent.rb b/lib/java_buildpack/framework/aspectj_weaver_agent.rb index ac9a3542e6..5412eaf41c 100644 --- a/lib/java_buildpack/framework/aspectj_weaver_agent.rb +++ b/lib/java_buildpack/framework/aspectj_weaver_agent.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/client_certificate_mapper.rb b/lib/java_buildpack/framework/client_certificate_mapper.rb index 3187985a06..ab9177c19c 100644 --- a/lib/java_buildpack/framework/client_certificate_mapper.rb +++ b/lib/java_buildpack/framework/client_certificate_mapper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/container_customizer.rb b/lib/java_buildpack/framework/container_customizer.rb index 1d50596a98..42f3dd89a0 100644 --- a/lib/java_buildpack/framework/container_customizer.rb +++ b/lib/java_buildpack/framework/container_customizer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/container_security_provider.rb b/lib/java_buildpack/framework/container_security_provider.rb index cadf261ac3..87ef12d00c 100644 --- a/lib/java_buildpack/framework/container_security_provider.rb +++ b/lib/java_buildpack/framework/container_security_provider.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index 2c50c26067..4006709899 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -58,19 +60,19 @@ def supports? private - API_KEY = 'api_key'.freeze + API_KEY = 'api_key' - FILTER = 'contrast-security'.freeze + FILTER = 'contrast-security' INFLECTION_VERSION = JavaBuildpack::Util::TokenizedVersion.new('3.4.3').freeze - PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins'.freeze + PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins' - SERVICE_KEY = 'service_key'.freeze + SERVICE_KEY = 'service_key' - TEAMSERVER_URL = 'teamserver_url'.freeze + TEAMSERVER_URL = 'teamserver_url' - USERNAME = 'username'.freeze + USERNAME = 'username' private_constant :API_KEY, :FILTER, :INFLECTION_VERSION, :PLUGIN_PACKAGE, :SERVICE_KEY, :TEAMSERVER_URL, :USERNAME diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index 0ff8605bb5..0de59b7a5e 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index 28db59f265..60e1433345 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -99,12 +101,12 @@ def write_cert(cert) def write_conf(servers, send_timeout, recv_timeout, retries) FileUtils.mkdir_p conf_file.parent conf_file.open(File::CREAT | File::WRONLY) do |f| - f.write < 0 + @configuration['max_dump_count'].to_i.positive? end end diff --git a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb index 04f92cb1e2..df6788c979 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -68,7 +70,7 @@ def release private # Matcher for service names or tags associated with the Java Memory Assistant - FILTER = 'heap-dump'.freeze + FILTER = 'heap-dump' def find_heap_dump_volume_service @application.services.find_volume_service FILTER diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index 50e9fa3154..ca3482edb4 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -46,9 +48,9 @@ def release private - CONFIGURATION_PROPERTY = 'java_opts'.freeze + CONFIGURATION_PROPERTY = 'java_opts' - ENVIRONMENT_PROPERTY = 'from_environment'.freeze + ENVIRONMENT_PROPERTY = 'from_environment' private_constant :CONFIGURATION_PROPERTY, :ENVIRONMENT_PROPERTY diff --git a/lib/java_buildpack/framework/java_security.rb b/lib/java_buildpack/framework/java_security.rb index 89e4d5b2e3..a2b4065ae3 100644 --- a/lib/java_buildpack/framework/java_security.rb +++ b/lib/java_buildpack/framework/java_security.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 50fa5cfb9d..8f5fbc4d8a 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index 0cb0341251..e2c08f0ae6 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 792099c9be..f547f7fc54 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -139,31 +141,31 @@ def write_configuration(servers, groups) chrystoki.open(File::APPEND | File::WRONLY) do |f| write_prologue f servers.each_with_index { |server, index| write_server f, index, server } - f.write < 0 + return "#{hours}h #{minutes}m" if hours.positive? seconds = (remainder / SECOND).to_int remainder -= SECOND * seconds - return "#{minutes}m #{seconds}s" if minutes > 0 + return "#{minutes}m #{seconds}s" if minutes.positive? tenths = (remainder / TENTH).to_int "#{seconds}.#{tenths}s" diff --git a/lib/java_buildpack/util/groovy_utils.rb b/lib/java_buildpack/util/groovy_utils.rb index 1f8a6432b4..5a67eec98e 100644 --- a/lib/java_buildpack/util/groovy_utils.rb +++ b/lib/java_buildpack/util/groovy_utils.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -68,7 +70,7 @@ def groovy_files(application) private - GROOVY_FILE_PATTERN = '**/*.groovy'.freeze + GROOVY_FILE_PATTERN = '**/*.groovy' private_constant :GROOVY_FILE_PATTERN diff --git a/lib/java_buildpack/util/jar_finder.rb b/lib/java_buildpack/util/jar_finder.rb index c4c415e3db..43a386f3a3 100644 --- a/lib/java_buildpack/util/jar_finder.rb +++ b/lib/java_buildpack/util/jar_finder.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/java_main_utils.rb b/lib/java_buildpack/util/java_main_utils.rb index b83e8e885c..cc6c292f39 100644 --- a/lib/java_buildpack/util/java_main_utils.rb +++ b/lib/java_buildpack/util/java_main_utils.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -48,9 +50,9 @@ def manifest(application) JavaBuildpack::Util::Properties.new(manifest_file) end - MAIN_CLASS_PROPERTY = 'java_main_class'.freeze + MAIN_CLASS_PROPERTY = 'java_main_class' - MANIFEST_PROPERTY = 'Main-Class'.freeze + MANIFEST_PROPERTY = 'Main-Class' private_constant :MAIN_CLASS_PROPERTY, :MANIFEST_PROPERTY diff --git a/lib/java_buildpack/util/play.rb b/lib/java_buildpack/util/play.rb index c0aed22ee0..6bc553d32f 100644 --- a/lib/java_buildpack/util/play.rb +++ b/lib/java_buildpack/util/play.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/base.rb b/lib/java_buildpack/util/play/base.rb index 8891e4311a..44efd6c2ef 100644 --- a/lib/java_buildpack/util/play/base.rb +++ b/lib/java_buildpack/util/play/base.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -64,7 +66,7 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - start_script && start_script.exist? && play_jar + start_script&.exist? && play_jar end # Returns the version of the play application @@ -121,9 +123,9 @@ def update_file(path, pattern, replacement) private - ORIGINAL_BOOTSTRAP = 'play.core.server.NettyServer'.freeze + ORIGINAL_BOOTSTRAP = 'play.core.server.NettyServer' - REPLACEMENT_BOOTSTRAP = 'org.cloudfoundry.reconfiguration.play.Bootstrap'.freeze + REPLACEMENT_BOOTSTRAP = 'org.cloudfoundry.reconfiguration.play.Bootstrap' private_constant :ORIGINAL_BOOTSTRAP, :REPLACEMENT_BOOTSTRAP diff --git a/lib/java_buildpack/util/play/factory.rb b/lib/java_buildpack/util/play/factory.rb index 8dc786c7ec..ee1c0ef2d9 100644 --- a/lib/java_buildpack/util/play/factory.rb +++ b/lib/java_buildpack/util/play/factory.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/post22.rb b/lib/java_buildpack/util/play/post22.rb index 8b88ea4edc..86438460ff 100644 --- a/lib/java_buildpack/util/play/post22.rb +++ b/lib/java_buildpack/util/play/post22.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/post22_dist.rb b/lib/java_buildpack/util/play/post22_dist.rb index 0c94ff8e8c..e5d0285655 100644 --- a/lib/java_buildpack/util/play/post22_dist.rb +++ b/lib/java_buildpack/util/play/post22_dist.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/post22_staged.rb b/lib/java_buildpack/util/play/post22_staged.rb index 26089228fe..a40ae2065c 100644 --- a/lib/java_buildpack/util/play/post22_staged.rb +++ b/lib/java_buildpack/util/play/post22_staged.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/pre22.rb b/lib/java_buildpack/util/play/pre22.rb index 9dba3ed6a7..9c53667fab 100644 --- a/lib/java_buildpack/util/play/pre22.rb +++ b/lib/java_buildpack/util/play/pre22.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/pre22_dist.rb b/lib/java_buildpack/util/play/pre22_dist.rb index 0e74712629..dd9ebe9906 100644 --- a/lib/java_buildpack/util/play/pre22_dist.rb +++ b/lib/java_buildpack/util/play/pre22_dist.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/play/pre22_staged.rb b/lib/java_buildpack/util/play/pre22_staged.rb index 0668d01ea8..66cfad97c3 100644 --- a/lib/java_buildpack/util/play/pre22_staged.rb +++ b/lib/java_buildpack/util/play/pre22_staged.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/properties.rb b/lib/java_buildpack/util/properties.rb index 7960389ca5..b563f73a67 100644 --- a/lib/java_buildpack/util/properties.rb +++ b/lib/java_buildpack/util/properties.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/qualify_path.rb b/lib/java_buildpack/util/qualify_path.rb index e54b49b802..024bc1930c 100644 --- a/lib/java_buildpack/util/qualify_path.rb +++ b/lib/java_buildpack/util/qualify_path.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/ratpack_utils.rb b/lib/java_buildpack/util/ratpack_utils.rb index 594a33595e..03c9ff9e32 100644 --- a/lib/java_buildpack/util/ratpack_utils.rb +++ b/lib/java_buildpack/util/ratpack_utils.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index 932986d7cd..c20f89a73e 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/shell.rb b/lib/java_buildpack/util/shell.rb index 08b8db693c..d8dbab8461 100644 --- a/lib/java_buildpack/util/shell.rb +++ b/lib/java_buildpack/util/shell.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/snake_case.rb b/lib/java_buildpack/util/snake_case.rb index 008a8e1df8..bc48bf3289 100644 --- a/lib/java_buildpack/util/snake_case.rb +++ b/lib/java_buildpack/util/snake_case.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/space_case.rb b/lib/java_buildpack/util/space_case.rb index 85d204f56c..35e809c9bf 100644 --- a/lib/java_buildpack/util/space_case.rb +++ b/lib/java_buildpack/util/space_case.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/spring_boot_utils.rb b/lib/java_buildpack/util/spring_boot_utils.rb index b668a9aad2..239e760e8d 100644 --- a/lib/java_buildpack/util/spring_boot_utils.rb +++ b/lib/java_buildpack/util/spring_boot_utils.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -43,16 +45,16 @@ def is?(application) # @return [String] the lib directory of Spring Boot used by the application def lib(droplet) candidate = manifest_lib_dir(droplet) - return candidate if candidate && candidate.exist? + return candidate if candidate&.exist? candidate = boot_inf_lib_dir(droplet) - return candidate if candidate && candidate.exist? + return candidate if candidate&.exist? candidate = web_inf_lib_dir(droplet) - return candidate if candidate && candidate.exist? + return candidate if candidate&.exist? candidate = lib_dir(droplet) - return candidate if candidate && candidate.exist? + return candidate if candidate&.exist? raise 'No lib directory found' end @@ -68,9 +70,9 @@ def version(application) private - SPRING_BOOT_LIB = 'Spring-Boot-Lib'.freeze + SPRING_BOOT_LIB = 'Spring-Boot-Lib' - SPRING_BOOT_VERSION = 'Spring-Boot-Version'.freeze + SPRING_BOOT_VERSION = 'Spring-Boot-Version' private_constant :SPRING_BOOT_LIB, :SPRING_BOOT_VERSION diff --git a/lib/java_buildpack/util/start_script.rb b/lib/java_buildpack/util/start_script.rb index b1f22da79f..a2e477c71f 100644 --- a/lib/java_buildpack/util/start_script.rb +++ b/lib/java_buildpack/util/start_script.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/to_b.rb b/lib/java_buildpack/util/to_b.rb index 1b54c33a59..c7776a5204 100644 --- a/lib/java_buildpack/util/to_b.rb +++ b/lib/java_buildpack/util/to_b.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index bd6483f320..3631ce9d75 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -23,7 +25,7 @@ class TokenizedVersion < Array include Comparable # The wildcard component. - WILDCARD = '+'.freeze + WILDCARD = '+' # Create a tokenized version based on the input string. # diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 4149f1cd60..5ff801f571 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -100,7 +102,7 @@ def cache def cache_task(uri) task uri do |t| @monitor.synchronize { rake_output_message "Caching #{t.name}" } - cache.get(t.name){} + cache.get(t.name) {} end uri diff --git a/rakelib/package.rb b/rakelib/package.rb index 4a611f7fbd..7be3a4f540 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -27,14 +29,14 @@ def self.version ARCHITECTURES = %w[x86_64].freeze - BUILD_DIR = 'build'.freeze + BUILD_DIR = 'build' BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze PLATFORMS = %w[trusty].freeze - STAGING_DIR = "#{BUILD_DIR}/staging".freeze + STAGING_DIR = "#{BUILD_DIR}/staging" - PACKAGE_NAME = "#{BUILD_DIR}/java-buildpack#{offline}-#{version}.zip".freeze + PACKAGE_NAME = "#{BUILD_DIR}/java-buildpack#{offline}-#{version}.zip" end diff --git a/rakelib/package_task.rb b/rakelib/package_task.rb index 22907dc2c1..a9eef61d14 100644 --- a/rakelib/package_task.rb +++ b/rakelib/package_task.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/rakelib/stage_buildpack_task.rb b/rakelib/stage_buildpack_task.rb index f01c5969f6..615200f658 100644 --- a/rakelib/stage_buildpack_task.rb +++ b/rakelib/stage_buildpack_task.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 0cd68d0845..cd7a1939ff 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/application_helper.rb b/spec/application_helper.rb index f1bb34b65b..adde4e71af 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/bin/compile_spec.rb b/spec/bin/compile_spec.rb index 5c59df207c..3b45bd1ef1 100644 --- a/spec/bin/compile_spec.rb +++ b/spec/bin/compile_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/bin/detect_spec.rb b/spec/bin/detect_spec.rb index 907a5e6127..b6bd3b916c 100644 --- a/spec/bin/detect_spec.rb +++ b/spec/bin/detect_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/bin/release_spec.rb b/spec/bin/release_spec.rb index 375c6595be..f85f98b4f3 100644 --- a/spec/bin/release_spec.rb +++ b/spec/bin/release_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/component_helper.rb b/spec/component_helper.rb index 8a46cee1f6..70e7561dc6 100644 --- a/spec/component_helper.rb +++ b/spec/component_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -63,7 +65,7 @@ tokenized_version = JavaBuildpack::Util::TokenizedVersion.new(version) allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item) do |&block| - block.call(tokenized_version) if block + block&.call(tokenized_version) end.and_return([tokenized_version, uri]) end diff --git a/spec/console_helper.rb b/spec/console_helper.rb index fa4e9e8020..976cdaf401 100644 --- a/spec/console_helper.rb +++ b/spec/console_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index da1ec95ac3..8bf79bfc33 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf index 294a1c1e7e..de6cd5fae3 100644 --- a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf @@ -57,8 +57,8 @@ HAConfiguration = { AutoReconnectInterval = 60; HAOnly = 1; reconnAtt = -1; - haLogStatus = enabled; - haLogToStdout = enabled; +haLogStatus = enabled; +haLogToStdout = enabled; } HASynchronize = { diff --git a/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb b/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb index d4964d7e2e..af8b061ea0 100644 --- a/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb +++ b/spec/fixtures/integration_long_detect_tag/lib/java_buildpack/container/long_detect_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index 0b5b784049..baebdaca5b 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/internet_availability_helper.rb b/spec/internet_availability_helper.rb index 8c8aaae689..e4628098d3 100644 --- a/spec/internet_availability_helper.rb +++ b/spec/internet_availability_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/buildpack_spec.rb b/spec/java_buildpack/buildpack_spec.rb index 4d033aa836..5e20559f26 100644 --- a/spec/java_buildpack/buildpack_spec.rb +++ b/spec/java_buildpack/buildpack_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/buildpack_version_spec.rb b/spec/java_buildpack/buildpack_version_spec.rb index da936b8ccf..08e798cb49 100644 --- a/spec/java_buildpack/buildpack_version_spec.rb +++ b/spec/java_buildpack/buildpack_version_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/additional_libraries_spec.rb b/spec/java_buildpack/component/additional_libraries_spec.rb index e151c3a02a..40a9336ef1 100644 --- a/spec/java_buildpack/component/additional_libraries_spec.rb +++ b/spec/java_buildpack/component/additional_libraries_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/application_spec.rb b/spec/java_buildpack/component/application_spec.rb index 585c4a7529..5225bd5463 100644 --- a/spec/java_buildpack/component/application_spec.rb +++ b/spec/java_buildpack/component/application_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/base_component_spec.rb b/spec/java_buildpack/component/base_component_spec.rb index 90654cbd97..5aaec0868f 100644 --- a/spec/java_buildpack/component/base_component_spec.rb +++ b/spec/java_buildpack/component/base_component_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/droplet_spec.rb b/spec/java_buildpack/component/droplet_spec.rb index ed68ee3ff4..7c4900ac90 100644 --- a/spec/java_buildpack/component/droplet_spec.rb +++ b/spec/java_buildpack/component/droplet_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/environment_variables_spec.rb b/spec/java_buildpack/component/environment_variables_spec.rb index 1e890d24ea..41ad03915e 100644 --- a/spec/java_buildpack/component/environment_variables_spec.rb +++ b/spec/java_buildpack/component/environment_variables_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/extension_directories_spec.rb b/spec/java_buildpack/component/extension_directories_spec.rb index 23879f276c..f596312dc6 100644 --- a/spec/java_buildpack/component/extension_directories_spec.rb +++ b/spec/java_buildpack/component/extension_directories_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index 1ce22fbed3..3cd4cef490 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/java_opts_spec.rb b/spec/java_buildpack/component/java_opts_spec.rb index 286dee4d42..bca3ad8e83 100644 --- a/spec/java_buildpack/component/java_opts_spec.rb +++ b/spec/java_buildpack/component/java_opts_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/modular_component_spec.rb b/spec/java_buildpack/component/modular_component_spec.rb index edc37d4b2d..ff8de578a5 100644 --- a/spec/java_buildpack/component/modular_component_spec.rb +++ b/spec/java_buildpack/component/modular_component_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/mutable_java_home_spec.rb b/spec/java_buildpack/component/mutable_java_home_spec.rb index ad063bde5c..4719bc408c 100644 --- a/spec/java_buildpack/component/mutable_java_home_spec.rb +++ b/spec/java_buildpack/component/mutable_java_home_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/security_providers_spec.rb b/spec/java_buildpack/component/security_providers_spec.rb index d118d04050..bc6d4aacbb 100644 --- a/spec/java_buildpack/component/security_providers_spec.rb +++ b/spec/java_buildpack/component/security_providers_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/services_spec.rb b/spec/java_buildpack/component/services_spec.rb index 174a750299..5f6d0a5437 100644 --- a/spec/java_buildpack/component/services_spec.rb +++ b/spec/java_buildpack/component/services_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/component/versioned_dependency_component_spec.rb b/spec/java_buildpack/component/versioned_dependency_component_spec.rb index c39b7ce75c..7d21907d6d 100644 --- a/spec/java_buildpack/component/versioned_dependency_component_spec.rb +++ b/spec/java_buildpack/component/versioned_dependency_component_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/dist_zip_like_spec.rb b/spec/java_buildpack/container/dist_zip_like_spec.rb index 257174dc75..ae4bca2255 100644 --- a/spec/java_buildpack/container/dist_zip_like_spec.rb +++ b/spec/java_buildpack/container/dist_zip_like_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/dist_zip_spec.rb b/spec/java_buildpack/container/dist_zip_spec.rb index a54ba549d9..bfd8ec7bc3 100644 --- a/spec/java_buildpack/container/dist_zip_spec.rb +++ b/spec/java_buildpack/container/dist_zip_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/groovy_spec.rb b/spec/java_buildpack/container/groovy_spec.rb index 38c15383d0..ca2aa509ca 100644 --- a/spec/java_buildpack/container/groovy_spec.rb +++ b/spec/java_buildpack/container/groovy_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index 24803fe1b2..0ce18af525 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/play_framework_spec.rb b/spec/java_buildpack/container/play_framework_spec.rb index 4544c90904..d88593a43e 100644 --- a/spec/java_buildpack/container/play_framework_spec.rb +++ b/spec/java_buildpack/container/play_framework_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/ratpack_spec.rb b/spec/java_buildpack/container/ratpack_spec.rb index 0e2755c06b..1318406105 100644 --- a/spec/java_buildpack/container/ratpack_spec.rb +++ b/spec/java_buildpack/container/ratpack_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/spring_boot_cli_spec.rb b/spec/java_buildpack/container/spring_boot_cli_spec.rb index 2cd48f38cb..300bff55e9 100644 --- a/spec/java_buildpack/container/spring_boot_cli_spec.rb +++ b/spec/java_buildpack/container/spring_boot_cli_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/spring_boot_spec.rb b/spec/java_buildpack/container/spring_boot_spec.rb index c7cae87c38..f6b8d2bd49 100644 --- a/spec/java_buildpack/container/spring_boot_spec.rb +++ b/spec/java_buildpack/container/spring_boot_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb index 33fecef2bc..eecc30b23f 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_access_logging_support_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb index 1831b7de03..664decc136 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index 8ed2df5667..a2bbfa0cc9 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb index 0aad953da4..3ca7c99732 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_insight_support_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb index fda99b2eb1..b1a8d858f1 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb index 92744a6b28..8222ca3911 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_lifecycle_support_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb index 281294826f..941fa579e2 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_logging_support_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb index 41956341d3..48c408e86c 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index 3e3133aac4..626cdcc898 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index adfedaed0a..7842231ac4 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb b/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb index b48fb34bb7..93de41cfcb 100644 --- a/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb +++ b/spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb index 17afbf62d1..172bdb6428 100644 --- a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb +++ b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/container_customizer_spec.rb b/spec/java_buildpack/framework/container_customizer_spec.rb index 354a77b002..c7de3b203a 100644 --- a/spec/java_buildpack/framework/container_customizer_spec.rb +++ b/spec/java_buildpack/framework/container_customizer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/container_security_provider_spec.rb b/spec/java_buildpack/framework/container_security_provider_spec.rb index 5f1dd60180..8cfb96bb39 100644 --- a/spec/java_buildpack/framework/container_security_provider_spec.rb +++ b/spec/java_buildpack/framework/container_security_provider_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb index 088767234f..08d0aa944c 100644 --- a/spec/java_buildpack/framework/contrast_security_agent_spec.rb +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2016 the original author or authors. # @@ -51,7 +53,7 @@ tokenized_version = JavaBuildpack::Util::TokenizedVersion.new('3.4.2_756') allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item) do |&block| - block.call(tokenized_version) if block + block&.call(tokenized_version) end.and_return([tokenized_version, uri]) component.release @@ -61,7 +63,7 @@ it 'uses java-agent for versions >= 3.4.3' do tokenized_version = JavaBuildpack::Util::TokenizedVersion.new('3.4.3_000') allow(JavaBuildpack::Repository::ConfiguredItem).to receive(:find_item) do |&block| - block.call(tokenized_version) if block + block&.call(tokenized_version) end.and_return([tokenized_version, uri]) component.release diff --git a/spec/java_buildpack/framework/debug_spec.rb b/spec/java_buildpack/framework/debug_spec.rb index 23d0640edc..0f0fc1876c 100644 --- a/spec/java_buildpack/framework/debug_spec.rb +++ b/spec/java_buildpack/framework/debug_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb index a8213658b3..ed4570cff5 100644 --- a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb +++ b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb index e3b27e647d..ed91b37be6 100644 --- a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 8f5445f61c..4b9dc9c058 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb b/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb index d848661562..5c505bf5dc 100644 --- a/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb +++ b/spec/java_buildpack/framework/google_stackdriver_debugger_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index d3a79e567e..3dea11d960 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb index 63e8c55762..b740a1703b 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb index 0c3046dc8c..a83b634cee 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb index a3d59ce6e4..1391a4f3bc 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/java_memory_assistant_spec.rb b/spec/java_buildpack/framework/java_memory_assistant_spec.rb index 74e9f32b5e..8d32ed9336 100644 --- a/spec/java_buildpack/framework/java_memory_assistant_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index c4394c54ea..141ed52987 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/java_security_spec.rb b/spec/java_buildpack/framework/java_security_spec.rb index f28dd1e5e8..a880ab2ff2 100644 --- a/spec/java_buildpack/framework/java_security_spec.rb +++ b/spec/java_buildpack/framework/java_security_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/jmx_spec.rb b/spec/java_buildpack/framework/jmx_spec.rb index 0354feca60..0a4fb8544c 100644 --- a/spec/java_buildpack/framework/jmx_spec.rb +++ b/spec/java_buildpack/framework/jmx_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb index 4bb3b4ee19..ea0dd76e06 100644 --- a/spec/java_buildpack/framework/jrebel_agent_spec.rb +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index c0066f6700..6b32d4e679 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/maria_db_jdbc_spec.rb b/spec/java_buildpack/framework/maria_db_jdbc_spec.rb index 896e509274..485987bc63 100644 --- a/spec/java_buildpack/framework/maria_db_jdbc_spec.rb +++ b/spec/java_buildpack/framework/maria_db_jdbc_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/metric_writer_spec.rb b/spec/java_buildpack/framework/metric_writer_spec.rb index bc3f631d97..885ae45759 100644 --- a/spec/java_buildpack/framework/metric_writer_spec.rb +++ b/spec/java_buildpack/framework/metric_writer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/multi_buildpack_spec.rb b/spec/java_buildpack/framework/multi_buildpack_spec.rb index ff64b3497f..35caea2d37 100644 --- a/spec/java_buildpack/framework/multi_buildpack_spec.rb +++ b/spec/java_buildpack/framework/multi_buildpack_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/new_relic_agent_spec.rb b/spec/java_buildpack/framework/new_relic_agent_spec.rb index 305a6dfe90..fb8186b155 100644 --- a/spec/java_buildpack/framework/new_relic_agent_spec.rb +++ b/spec/java_buildpack/framework/new_relic_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/postgresql_jdbc_spec.rb b/spec/java_buildpack/framework/postgresql_jdbc_spec.rb index cc2eb7d4bf..953a6e8510 100644 --- a/spec/java_buildpack/framework/postgresql_jdbc_spec.rb +++ b/spec/java_buildpack/framework/postgresql_jdbc_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb index 8f3e80aad5..9713aacc78 100644 --- a/spec/java_buildpack/framework/protect_app_security_provider_spec.rb +++ b/spec/java_buildpack/framework/protect_app_security_provider_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2016 the original author or authors. # diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index 8015044207..2b0b62b684 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/spring_insight_spec.rb b/spec/java_buildpack/framework/spring_insight_spec.rb index ddd889eb34..a9af6270f4 100644 --- a/spec/java_buildpack/framework/spring_insight_spec.rb +++ b/spec/java_buildpack/framework/spring_insight_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/takipi_agent_spec.rb b/spec/java_buildpack/framework/takipi_agent_spec.rb index 83e7998d2e..f6a6a52035 100644 --- a/spec/java_buildpack/framework/takipi_agent_spec.rb +++ b/spec/java_buildpack/framework/takipi_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/framework/your_kit_profiler_spec.rb b/spec/java_buildpack/framework/your_kit_profiler_spec.rb index 42968b82ec..a8991ac7a0 100644 --- a/spec/java_buildpack/framework/your_kit_profiler_spec.rb +++ b/spec/java_buildpack/framework/your_kit_profiler_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb b/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb index e8377d05cc..6c9e43db0e 100644 --- a/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_initializer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/ibm_jre_spec.rb b/spec/java_buildpack/jre/ibm_jre_spec.rb index efd7c730af..3c4e750704 100644 --- a/spec/java_buildpack/jre/ibm_jre_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/jvmkill_agent_spec.rb b/spec/java_buildpack/jre/jvmkill_agent_spec.rb index 0b0f2f7764..54e9bddafd 100644 --- a/spec/java_buildpack/jre/jvmkill_agent_spec.rb +++ b/spec/java_buildpack/jre/jvmkill_agent_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2016 the original author or authors. # diff --git a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index d04858bc63..d79ac980a4 100644 --- a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 3acaf5718b..c743c1e374 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb b/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb index 1dbab5b413..e9a02bc774 100644 --- a/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_security_providers_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index fc7cd720e7..2ed4bcd7ce 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/logging/delegating_logger_spec.rb b/spec/java_buildpack/logging/delegating_logger_spec.rb index ba789d0547..6980ae0761 100644 --- a/spec/java_buildpack/logging/delegating_logger_spec.rb +++ b/spec/java_buildpack/logging/delegating_logger_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/logging/logger_factory_spec.rb b/spec/java_buildpack/logging/logger_factory_spec.rb index f3f9bd86bf..6a50f0612c 100644 --- a/spec/java_buildpack/logging/logger_factory_spec.rb +++ b/spec/java_buildpack/logging/logger_factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/repository/configured_item_spec.rb b/spec/java_buildpack/repository/configured_item_spec.rb index 3e15952798..4173a212e7 100644 --- a/spec/java_buildpack/repository/configured_item_spec.rb +++ b/spec/java_buildpack/repository/configured_item_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/repository/repository_index_spec.rb b/spec/java_buildpack/repository/repository_index_spec.rb index 39f52a3f10..9414151893 100644 --- a/spec/java_buildpack/repository/repository_index_spec.rb +++ b/spec/java_buildpack/repository/repository_index_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/repository/version_resolver_spec.rb b/spec/java_buildpack/repository/version_resolver_spec.rb index 59cbb11a27..9d4d7e084e 100644 --- a/spec/java_buildpack/repository/version_resolver_spec.rb +++ b/spec/java_buildpack/repository/version_resolver_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/cache/application_cache_spec.rb b/spec/java_buildpack/util/cache/application_cache_spec.rb index bd28d1cc9e..39b6ec3235 100644 --- a/spec/java_buildpack/util/cache/application_cache_spec.rb +++ b/spec/java_buildpack/util/cache/application_cache_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -50,7 +52,7 @@ it 'uses ARGV[1] directory' do ARGV[1] = app_dir - described_class.new.get('http://foo-uri/'){} + described_class.new.get('http://foo-uri/') {} expect(Pathname.glob(app_dir + '*.cached').size).to eq(1) end diff --git a/spec/java_buildpack/util/cache/cache_factory_spec.rb b/spec/java_buildpack/util/cache/cache_factory_spec.rb index 3ac294134e..00bfae1523 100644 --- a/spec/java_buildpack/util/cache/cache_factory_spec.rb +++ b/spec/java_buildpack/util/cache/cache_factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/cache/cached_file_spec.rb b/spec/java_buildpack/util/cache/cached_file_spec.rb index ea1460e4ca..93f1459a80 100644 --- a/spec/java_buildpack/util/cache/cached_file_spec.rb +++ b/spec/java_buildpack/util/cache/cached_file_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 8a903dafdb..5670b1fdd0 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # @@ -199,7 +201,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:Proxy).with('proxy', 9000, nil, nil).and_call_original - download_cache.get(uri){} + download_cache.get(uri) {} end end @@ -216,7 +218,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:Proxy).with('proxy', 9000, nil, nil).and_call_original - download_cache.get(uri){} + download_cache.get(uri) {} end end @@ -233,7 +235,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:Proxy).with('proxy', 9000, nil, nil).and_call_original - download_cache.get(uri_secure){} + download_cache.get(uri_secure) {} end end @@ -250,7 +252,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:Proxy).with('proxy', 9000, nil, nil).and_call_original - download_cache.get(uri_secure){} + download_cache.get(uri_secure) {} end end @@ -266,7 +268,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original expect(Net::HTTP).not_to have_received(:Proxy).with('proxy', 9000, nil, nil) - download_cache.get(uri_secure){} + download_cache.get(uri_secure) {} end end @@ -282,7 +284,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original expect(Net::HTTP).not_to have_received(:Proxy).with('proxy', 9000, nil, nil) - download_cache.get(uri_secure){} + download_cache.get(uri_secure) {} end end @@ -294,7 +296,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original - download_cache.get(uri){} + download_cache.get(uri) {} end it 'does not use ca_file if the URL is not secure and directory does exist' do @@ -305,7 +307,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original - download_cache.get(uri){} + download_cache.get(uri) {} end it 'does not use ca_file if the URL is secure and directory does not exist' do @@ -315,7 +317,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:start).with('foo-uri', 443, use_ssl: true).and_call_original - download_cache.get(uri_secure){} + download_cache.get(uri_secure) {} end it 'uses ca_file if the URL is secure and directory does exist' do @@ -326,7 +328,7 @@ allow(Net::HTTP).to receive(:Proxy).and_call_original allow(Net::HTTP).to receive(:start).with('foo-uri', 443, use_ssl: true, ca_file: 'test-path').and_call_original - download_cache.get(uri_secure){} + download_cache.get(uri_secure) {} end it 'deletes the cached file if it exists' do diff --git a/spec/java_buildpack/util/cache/internet_availability_spec.rb b/spec/java_buildpack/util/cache/internet_availability_spec.rb index 3796d07d24..d6eb123fb7 100644 --- a/spec/java_buildpack/util/cache/internet_availability_spec.rb +++ b/spec/java_buildpack/util/cache/internet_availability_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/cache/yield_file_with_content.rb b/spec/java_buildpack/util/cache/yield_file_with_content.rb index 49d29b9911..d07b4f94ef 100644 --- a/spec/java_buildpack/util/cache/yield_file_with_content.rb +++ b/spec/java_buildpack/util/cache/yield_file_with_content.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 97381e67e4..7c0c499985 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/constantize_spec.rb b/spec/java_buildpack/util/constantize_spec.rb index 9d11559e02..d51cd3c8de 100644 --- a/spec/java_buildpack/util/constantize_spec.rb +++ b/spec/java_buildpack/util/constantize_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index 5a166685b5..ef100b1190 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/format_duration_spec.rb b/spec/java_buildpack/util/format_duration_spec.rb index a1a526ab5c..aa048912a6 100644 --- a/spec/java_buildpack/util/format_duration_spec.rb +++ b/spec/java_buildpack/util/format_duration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/java_main_utils_spec.rb b/spec/java_buildpack/util/java_main_utils_spec.rb index 1453d692ed..f22c71ced3 100644 --- a/spec/java_buildpack/util/java_main_utils_spec.rb +++ b/spec/java_buildpack/util/java_main_utils_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/base_spec.rb b/spec/java_buildpack/util/play/base_spec.rb index a11e2e00ca..9e233c6c46 100644 --- a/spec/java_buildpack/util/play/base_spec.rb +++ b/spec/java_buildpack/util/play/base_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/factory_spec.rb b/spec/java_buildpack/util/play/factory_spec.rb index cef4838c4b..75566bfc08 100644 --- a/spec/java_buildpack/util/play/factory_spec.rb +++ b/spec/java_buildpack/util/play/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/post22_dist_spec.rb b/spec/java_buildpack/util/play/post22_dist_spec.rb index dc834bc293..f6d42b6fc1 100644 --- a/spec/java_buildpack/util/play/post22_dist_spec.rb +++ b/spec/java_buildpack/util/play/post22_dist_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index 58a1cecb2d..7b3aebac74 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/post22_staged_spec.rb b/spec/java_buildpack/util/play/post22_staged_spec.rb index a7f362be73..d039c487e0 100644 --- a/spec/java_buildpack/util/play/post22_staged_spec.rb +++ b/spec/java_buildpack/util/play/post22_staged_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index aaf98a9228..c88c82af29 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/pre22_spec.rb b/spec/java_buildpack/util/play/pre22_spec.rb index 576ac000bc..f34ebccedc 100644 --- a/spec/java_buildpack/util/play/pre22_spec.rb +++ b/spec/java_buildpack/util/play/pre22_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index de5b67b57e..00d2805bb7 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/properties_spec.rb b/spec/java_buildpack/util/properties_spec.rb index a9fcb8e118..22533a8b74 100644 --- a/spec/java_buildpack/util/properties_spec.rb +++ b/spec/java_buildpack/util/properties_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/ratpack_utils_spec.rb b/spec/java_buildpack/util/ratpack_utils_spec.rb index 73c89d23d7..4b828591c2 100644 --- a/spec/java_buildpack/util/ratpack_utils_spec.rb +++ b/spec/java_buildpack/util/ratpack_utils_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/sanitize_spec.rb b/spec/java_buildpack/util/sanitize_spec.rb index 11770bd838..074cd7ce90 100644 --- a/spec/java_buildpack/util/sanitize_spec.rb +++ b/spec/java_buildpack/util/sanitize_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/shell_spec.rb b/spec/java_buildpack/util/shell_spec.rb index 3caefc0ffd..f79c72fac7 100644 --- a/spec/java_buildpack/util/shell_spec.rb +++ b/spec/java_buildpack/util/shell_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/spring_boot_utils_spec.rb b/spec/java_buildpack/util/spring_boot_utils_spec.rb index c64e20b2c7..bb739b4177 100644 --- a/spec/java_buildpack/util/spring_boot_utils_spec.rb +++ b/spec/java_buildpack/util/spring_boot_utils_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/java_buildpack/util/tokenized_version_spec.rb b/spec/java_buildpack/util/tokenized_version_spec.rb index 1e5f3fac21..126cc5f259 100644 --- a/spec/java_buildpack/util/tokenized_version_spec.rb +++ b/spec/java_buildpack/util/tokenized_version_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/logging_helper.rb b/spec/logging_helper.rb index 9ea15eaf41..56c7a71549 100644 --- a/spec/logging_helper.rb +++ b/spec/logging_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/memory_limit_helper.rb b/spec/memory_limit_helper.rb index a32bb74afe..0f70008759 100644 --- a/spec/memory_limit_helper.rb +++ b/spec/memory_limit_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dca5ec4181..f09bf098f9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Cloud Foundry Java Buildpack # Copyright 2013-2017 the original author or authors. # From bdc73f3fdf2735b803c02d9dfd66da3e59fdf1e2 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 17 Jan 2018 11:46:40 -0800 Subject: [PATCH 393/812] Polishing --- .idea/.rakeTasks | 2 +- .idea/runConfigurations/rubocop.xml | 4 ++-- .idea/runConfigurations/versions.xml | 4 ++-- .idea/runConfigurations/versions__Markdown_.xml | 4 ++-- .idea/runConfigurations/versions__Pivotal_Network_.xml | 4 ++-- .idea/runConfigurations/versions__YAML_.xml | 4 ++-- java-buildpack.iml | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index 23d30fbda3..6db1428532 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/.idea/runConfigurations/rubocop.xml b/.idea/runConfigurations/rubocop.xml index c43c11bf4f..d363b94a8f 100644 --- a/.idea/runConfigurations/rubocop.xml +++ b/.idea/runConfigurations/rubocop.xml @@ -4,10 +4,10 @@ - + - + diff --git a/.idea/runConfigurations/versions.xml b/.idea/runConfigurations/versions.xml index 36aac7eca9..31c0dbcaa5 100644 --- a/.idea/runConfigurations/versions.xml +++ b/.idea/runConfigurations/versions.xml @@ -4,10 +4,10 @@ - + - + diff --git a/.idea/runConfigurations/versions__Markdown_.xml b/.idea/runConfigurations/versions__Markdown_.xml index 45b443aeaf..6b7ebbb7d2 100644 --- a/.idea/runConfigurations/versions__Markdown_.xml +++ b/.idea/runConfigurations/versions__Markdown_.xml @@ -4,10 +4,10 @@ - + - + diff --git a/.idea/runConfigurations/versions__Pivotal_Network_.xml b/.idea/runConfigurations/versions__Pivotal_Network_.xml index 6b946e443b..055e603872 100644 --- a/.idea/runConfigurations/versions__Pivotal_Network_.xml +++ b/.idea/runConfigurations/versions__Pivotal_Network_.xml @@ -4,10 +4,10 @@ - + - + diff --git a/.idea/runConfigurations/versions__YAML_.xml b/.idea/runConfigurations/versions__YAML_.xml index 1acd036c8b..0dd45fc663 100644 --- a/.idea/runConfigurations/versions__YAML_.xml +++ b/.idea/runConfigurations/versions__YAML_.xml @@ -4,10 +4,10 @@ - + - + diff --git a/java-buildpack.iml b/java-buildpack.iml index c1dd94d3e9..b191fdd1f3 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -285,15 +285,15 @@ - - + + - + From 5540dd15609aee8a082a99a72eed040d6e059b0b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 17 Jan 2018 12:39:46 -0800 Subject: [PATCH 394/812] Copyright Updates --- resources/tomcat/conf/context.xml | 2 +- resources/tomcat/conf/logging.properties | 2 +- resources/tomcat/conf/server.xml | 6 +++--- spec/fixtures/container_groovy_logback/Alpha.java | 2 +- .../container_groovy_logback/ch/qos/logback/pogo.groovy | 2 +- spec/fixtures/container_groovy_main_method/Alpha.groovy | 2 +- .../container_groovy_main_method/Application.groovy | 2 +- .../container_groovy_main_method/directory/Beta.groovy | 2 +- spec/fixtures/container_groovy_non_pogo/Alpha.groovy | 2 +- spec/fixtures/container_groovy_non_pogo/Application.groovy | 2 +- .../logback.groovy | 2 +- spec/fixtures/container_groovy_shebang/Alpha.groovy | 2 +- spec/fixtures/container_groovy_shebang/Application.groovy | 2 +- .../Application.groovy | 2 +- spec/fixtures/container_groovy_with_jars/Application.groovy | 2 +- .../application-root/app/Ratpack.groovy | 2 +- spec/fixtures/container_ratpack_staged/app/ratpack.groovy | 2 +- .../configuration.groovy | 2 +- .../pogo_1.groovy | 2 +- .../pogo.groovy | 2 +- .../container_spring_boot_cli_main_method/main.groovy | 2 +- .../container_spring_boot_cli_main_method/pogo.groovy | 2 +- .../container_spring_boot_cli_non_pogo/non_pogo.groovy | 2 +- .../fixtures/container_spring_boot_cli_non_pogo/pogo.groovy | 2 +- .../directory/pogo_4.groovy | 2 +- .../container_spring_boot_cli_valid_app/pogo_1.groovy | 2 +- .../container_spring_boot_cli_valid_app/pogo_2.groovy | 2 +- .../container_spring_boot_cli_valid_app/pogo_3.groovy | 2 +- .../.java-buildpack/tomcat/conf/context.xml | 2 +- .../.java-buildpack/tomcat/conf/server.xml | 6 +++--- .../fixtures/container_tomcat_geode_store_context_after.xml | 2 +- spec/fixtures/container_tomcat_geode_store_server_after.xml | 6 +++--- .../.java-buildpack/tomcat/conf/context.xml | 2 +- .../fixtures/container_tomcat_redis_store_context_after.xml | 2 +- spec/fixtures/container_tomcat_with_index/index.html | 2 +- spec/fixtures/framework_jrebel_app_simple/rebel-remote.xml | 2 +- .../WEB-INF/classes/rebel-remote.xml | 2 +- spec/fixtures/integration_valid/system.properties | 2 +- spec/fixtures/test.properties | 2 +- 39 files changed, 45 insertions(+), 45 deletions(-) diff --git a/resources/tomcat/conf/context.xml b/resources/tomcat/conf/context.xml index 1185529579..84e432bcf6 100644 --- a/resources/tomcat/conf/context.xml +++ b/resources/tomcat/conf/context.xml @@ -1,6 +1,6 @@ +--> diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 6b46d21ce6..46f83bd0d3 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,8 +1,5 @@ - - diff --git a/.idea/runConfigurations/All_Tests__2_3_.xml b/.idea/runConfigurations/All_Tests__2_3_.xml index 92c132a81e..12db3db056 100644 --- a/.idea/runConfigurations/All_Tests__2_3_.xml +++ b/.idea/runConfigurations/All_Tests__2_3_.xml @@ -5,14 +5,14 @@ - + - + diff --git a/.idea/runConfigurations/All_Tests__2_4_.xml b/.idea/runConfigurations/All_Tests__2_4_.xml index 3695657f1a..ef434cddc0 100644 --- a/.idea/runConfigurations/All_Tests__2_4_.xml +++ b/.idea/runConfigurations/All_Tests__2_4_.xml @@ -5,14 +5,14 @@ - + - + diff --git a/.idea/runConfigurations/All_Tests__2_5_.xml b/.idea/runConfigurations/All_Tests__2_5_.xml index e6f973adb7..8495593f65 100644 --- a/.idea/runConfigurations/All_Tests__2_5_.xml +++ b/.idea/runConfigurations/All_Tests__2_5_.xml @@ -5,14 +5,14 @@ - + - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml index a20038c22a..18a752c5d9 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml @@ -5,14 +5,14 @@ - + - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml index cad6c77106..0582ee9adb 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml @@ -5,14 +5,14 @@ - + - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml index 75a1a5cce2..12f1e6ad3e 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml @@ -5,14 +5,14 @@ - + - + diff --git a/java-buildpack.iml b/java-buildpack.iml index b191fdd1f3..1ccd43a5a1 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -265,36 +265,36 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b415ca6a55c10cc859d963cc0d3343beb953ec46 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 2 May 2018 15:17:04 -0400 Subject: [PATCH 413/812] Improve Auto-Reconfiguration Documentation This change updates the documentation for Spring Auto-Reconfiguration to point to other documentation containing details about how bean replacement is achieved. [resolves #581] --- docs/framework-spring_auto_reconfiguration.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/framework-spring_auto_reconfiguration.md b/docs/framework-spring_auto_reconfiguration.md index d8e8fbce85..c13280acde 100644 --- a/docs/framework-spring_auto_reconfiguration.md +++ b/docs/framework-spring_auto_reconfiguration.md @@ -13,7 +13,7 @@ The Spring Auto-reconfiguration Framework causes an application to be automatica Tags are printed to standard output by the buildpack detect script -The Spring Auto-reconfiguration Framework adds the `cloud` profile to any existing Spring profiles such as those defined in the [`SPRING_PROFILES_ACTIVE`][] environment variable. +The Spring Auto-reconfiguration Framework adds the `cloud` profile to any existing Spring profiles such as those defined in the [`SPRING_PROFILES_ACTIVE`][] environment variable. It also uses the [Spring Cloud Cloud Foundry Connector][] to replace any bean of a candidate type with one mapped to a bound service instance. Please see the [Auto-Reconfiguration][] project for more details. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. @@ -26,9 +26,11 @@ The framework can be configured by modifying the [`config/spring_auto_reconfigur | `repository_root` | The URL of the Auto-reconfiguration repository index ([details][repositories]). | `version` | The version of Auto-reconfiguration to use. Candidate versions can be found in [this listing][]. +[Auto-Reconfiguration]: https://github.com/cloudfoundry/java-buildpack-auto-reconfiguration [Configuration and Extension]: ../README.md#configuration-and-extension [`config/spring_auto_reconfiguration.yml`]: ../config/spring_auto_reconfiguration.yml [repositories]: extending-repositories.md +[Spring Cloud Cloud Foundry Connector]: https://cloud.spring.io/spring-cloud-connectors/spring-cloud-cloud-foundry-connector.html [this listing]: http://download.pivotal.io.s3.amazonaws.com/auto-reconfiguration/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering [`SPRING_PROFILES_ACTIVE`]: http://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/org/springframework/core/env/AbstractEnvironment.html#ACTIVE_PROFILES_PROPERTY_NAME From 887784c0a130387f8af9883fb7955b0f9e02edf3 Mon Sep 17 00:00:00 2001 From: gm2552 Date: Wed, 2 May 2018 17:48:44 -0500 Subject: [PATCH 414/812] Support for TCPKeepAlive configuration This enhancement supports configuring the TCPKeepAlive setting in Luna Security Provider. Configuration is done by setting the tcp_keep_alive_enabled configuration parameter to true of false (default is false). Default behavior sets the TCPKeepAlive Luna client parameter to 0 which is the default setting if the parameter is not present in the Chryptoki.conf file. [#589] --- config/luna_security_provider.yml | 1 + docs/framework-luna_security_provider.md | 1 + .../framework/luna_security_provider.rb | 5 ++ .../Chrystoki.conf | 1 + .../Chrystoki.conf | 1 + .../Chrystoki.conf | 68 +++++++++++++++++++ .../client-certificate.pem | 3 + .../client-private-key.pem | 3 + .../server-certificates.pem | 6 ++ .../framework/luna_security_provider_spec.rb | 28 +++++++- 10 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf create mode 100644 spec/fixtures/framework_luna_security_provider_tcp_keep_alive/client-certificate.pem create mode 100644 spec/fixtures/framework_luna_security_provider_tcp_keep_alive/client-private-key.pem create mode 100644 spec/fixtures/framework_luna_security_provider_tcp_keep_alive/server-certificates.pem diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index 98daf90dcd..94c96b6b1c 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -19,3 +19,4 @@ version: 6.+ repository_root: http://files.cf-hsm.io/luna-installer ha_logging_enabled: true logging_enabled: false +tcp_keep_alive_enabled: false \ No newline at end of file diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md index 2846a37fb5..a749dedfb6 100644 --- a/docs/framework-luna_security_provider.md +++ b/docs/framework-luna_security_provider.md @@ -93,6 +93,7 @@ The framework can be configured by modifying the [`config/luna_security_provider | ---- | ----------- | `ha_logging_enabled` | Whether to enable HA logging for the Luna Security Provider. Defaults to `true`. | `logging_enabled` | Whether to enable the logging wrapper for the Luna Security Provider. Defaults to `false`. +| `tcp_keep_alive_enabled` | Whether to enable the client TCP keep alive setting for the Luna Security Provider. Defaults to `false`. | `repository_root` | The URL of the Luna Security Provider repository index ([details][repositories]). | `version` | Version of the Luna Security Provider to use. diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 56e9c456f0..7bc7d14588 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -113,6 +113,10 @@ def ha_logging? @configuration['ha_logging_enabled'] end + def tcp_keep_alive + @configuration['tcp_keep_alive_enabled'] ? 1 : 0 + end + def padded_index(index) index.to_s.rjust(2, '0') end @@ -223,6 +227,7 @@ def write_prologue(f) f.write <<~CLIENT LunaSA Client = { + TCPKeepAlive = #{tcp_keep_alive}; NetClient = 1; ClientCertFile = #{relative(client_certificate)}; diff --git a/spec/fixtures/framework_luna_security_provider/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider/Chrystoki.conf index 3a79d2b596..28fda4eed3 100644 --- a/spec/fixtures/framework_luna_security_provider/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider/Chrystoki.conf @@ -17,6 +17,7 @@ Chrystoki2 = { } LunaSA Client = { + TCPKeepAlive = 0; NetClient = 1; ClientCertFile = .java-buildpack/luna_security_provider/client-certificate.pem; diff --git a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf index de6cd5fae3..fbe0f799d8 100644 --- a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf @@ -25,6 +25,7 @@ CkLog2 = { } LunaSA Client = { + TCPKeepAlive = 0; NetClient = 1; ClientCertFile = .java-buildpack/luna_security_provider/client-certificate.pem; diff --git a/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf new file mode 100644 index 0000000000..ceadccc0c5 --- /dev/null +++ b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf @@ -0,0 +1,68 @@ +Luna = { + CloningCommandTimeOut = 300000; + CommandTimeOutPedSet = 720000; + DefaultTimeOut = 500000; + KeypairGenTimeOut = 2700000; + PEDTimeout1 = 100000; + PEDTimeout2 = 200000; + PEDTimeout3 = 10000; +} + +Misc = { + PE1746Enabled = 0; +} + +Chrystoki2 = { + LibUNIX64 = .java-buildpack/luna_security_provider/libs/64/libcklog2.so; +} + +CkLog2 = { + Enabled = 1; + LibUNIX64 = .java-buildpack/luna_security_provider/libs/64/libCryptoki2.so; + LoggingMask = ALL_FUNC; + LogToStreams = 1; + NewFormat = 1; +} + +LunaSA Client = { + TCPKeepAlive = 1; + NetClient = 1; + + ClientCertFile = .java-buildpack/luna_security_provider/client-certificate.pem; + ClientPrivKeyFile = .java-buildpack/luna_security_provider/client-private-key.pem; + HtlDir = .java-buildpack/luna_security_provider/htl; + ServerCAFile = .java-buildpack/luna_security_provider/server-certificates.pem; + + ServerName00 = test-server-1; + ServerPort00 = 1792; + ServerHtl00 = 0; + + ServerName01 = test-server-2; + ServerPort01 = 1792; + ServerHtl01 = 0; + +} + +VirtualToken = { + VirtualToken00Label = test-group-1; + VirtualToken00SN = 1test-group-1-member-1; + VirtualToken00Members = test-group-1-member-1,test-group-1-member-2; + + VirtualToken01Label = test-group-2; + VirtualToken01SN = 1test-group-2-member-1; + VirtualToken01Members = test-group-2-member-1,test-group-2-member-2; + +} + +HAConfiguration = { + AutoReconnectInterval = 60; + HAOnly = 1; + reconnAtt = -1; +haLogStatus = enabled; +haLogToStdout = enabled; +} + +HASynchronize = { + test-group-1 = 1; + test-group-2 = 1; +} diff --git a/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/client-certificate.pem b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/client-certificate.pem new file mode 100644 index 0000000000..40769aae71 --- /dev/null +++ b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/client-certificate.pem @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +test-client-cert +-----END CERTIFICATE----- diff --git a/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/client-private-key.pem b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/client-private-key.pem new file mode 100644 index 0000000000..019359d6ba --- /dev/null +++ b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/client-private-key.pem @@ -0,0 +1,3 @@ +-----BEGIN RSA PRIVATE KEY----- +test-client-private-key +-----END RSA PRIVATE KEY----- diff --git a/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/server-certificates.pem b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/server-certificates.pem new file mode 100644 index 0000000000..ea7e60aa91 --- /dev/null +++ b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/server-certificates.pem @@ -0,0 +1,6 @@ +-----BEGIN CERTIFICATE----- +test-server-1-cert +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +test-server-2-cert +-----END CERTIFICATE----- diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index 7603322b9c..5809e89603 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -159,7 +159,13 @@ end context do - let(:configuration) { { 'logging_enabled' => true, 'ha_logging_enabled' => true } } + let(:configuration) do + { + 'logging_enabled' => true, + 'ha_logging_enabled' => true, + 'tcp_keep_alive_enabled' => false + } + end it 'writes configuration', cache_fixture: 'stub-luna-security-provider.tar' do @@ -172,6 +178,26 @@ end end + context do + let(:configuration) do + { + 'logging_enabled' => true, + 'ha_logging_enabled' => true, + 'tcp_keep_alive_enabled' => true + } + end + + it 'writes configuration with client tcp keep alive', + cache_fixture: 'stub-luna-security-provider.tar' do + + component.compile + + expect(sandbox + 'Chrystoki.conf').to exist + check_file_contents(sandbox + 'Chrystoki.conf', + 'spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf') + end + end + def check_file_contents(actual, expected) expect(File.read(actual)).to eq File.read(expected) end From 47b3dfd2a174805ee65620760cd8d53a91322eef Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 2 May 2018 19:20:06 -0400 Subject: [PATCH 415/812] Polishing [resolves #589] --- config/luna_security_provider.yml | 2 +- lib/java_buildpack/framework/luna_security_provider.rb | 10 +++++----- .../framework_luna_security_provider/Chrystoki.conf | 6 +++--- .../Chrystoki.conf | 10 +++++----- .../Chrystoki.conf | 10 +++++----- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index 94c96b6b1c..22702c2eee 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -19,4 +19,4 @@ version: 6.+ repository_root: http://files.cf-hsm.io/luna-installer ha_logging_enabled: true logging_enabled: false -tcp_keep_alive_enabled: false \ No newline at end of file +tcp_keep_alive_enabled: false diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 7bc7d14588..9a25dffc9b 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -161,8 +161,8 @@ def write_epilogue(f, groups) HAConfiguration = { AutoReconnectInterval = 60; - HAOnly = 1; - reconnAtt = -1; + HAOnly = 1; + reconnAtt = -1; HA write_ha_logging(f) if ha_logging? f.write <<~HA @@ -216,8 +216,8 @@ def write_logging(f) def write_ha_logging(f) f.write <<~HA - haLogStatus = enabled; - haLogToStdout = enabled; + haLogStatus = enabled; + haLogToStdout = enabled; HA end @@ -228,7 +228,7 @@ def write_prologue(f) LunaSA Client = { TCPKeepAlive = #{tcp_keep_alive}; - NetClient = 1; + NetClient = 1; ClientCertFile = #{relative(client_certificate)}; ClientPrivKeyFile = #{relative(client_private_key)}; diff --git a/spec/fixtures/framework_luna_security_provider/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider/Chrystoki.conf index 28fda4eed3..9ee5e344ba 100644 --- a/spec/fixtures/framework_luna_security_provider/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider/Chrystoki.conf @@ -18,7 +18,7 @@ Chrystoki2 = { LunaSA Client = { TCPKeepAlive = 0; - NetClient = 1; + NetClient = 1; ClientCertFile = .java-buildpack/luna_security_provider/client-certificate.pem; ClientPrivKeyFile = .java-buildpack/luna_security_provider/client-private-key.pem; @@ -48,8 +48,8 @@ VirtualToken = { HAConfiguration = { AutoReconnectInterval = 60; - HAOnly = 1; - reconnAtt = -1; + HAOnly = 1; + reconnAtt = -1; } HASynchronize = { diff --git a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf index fbe0f799d8..df355a691b 100644 --- a/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider_logging/Chrystoki.conf @@ -26,7 +26,7 @@ CkLog2 = { LunaSA Client = { TCPKeepAlive = 0; - NetClient = 1; + NetClient = 1; ClientCertFile = .java-buildpack/luna_security_provider/client-certificate.pem; ClientPrivKeyFile = .java-buildpack/luna_security_provider/client-private-key.pem; @@ -56,10 +56,10 @@ VirtualToken = { HAConfiguration = { AutoReconnectInterval = 60; - HAOnly = 1; - reconnAtt = -1; -haLogStatus = enabled; -haLogToStdout = enabled; + HAOnly = 1; + reconnAtt = -1; +haLogStatus = enabled; +haLogToStdout = enabled; } HASynchronize = { diff --git a/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf index ceadccc0c5..96eeadd2cc 100644 --- a/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf +++ b/spec/fixtures/framework_luna_security_provider_tcp_keep_alive/Chrystoki.conf @@ -26,7 +26,7 @@ CkLog2 = { LunaSA Client = { TCPKeepAlive = 1; - NetClient = 1; + NetClient = 1; ClientCertFile = .java-buildpack/luna_security_provider/client-certificate.pem; ClientPrivKeyFile = .java-buildpack/luna_security_provider/client-private-key.pem; @@ -56,10 +56,10 @@ VirtualToken = { HAConfiguration = { AutoReconnectInterval = 60; - HAOnly = 1; - reconnAtt = -1; -haLogStatus = enabled; -haLogToStdout = enabled; + HAOnly = 1; + reconnAtt = -1; +haLogStatus = enabled; +haLogToStdout = enabled; } HASynchronize = { From 1977b77a914ebcf104e0289d5f7e7a9f66a3daa3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 3 May 2018 11:06:57 -0400 Subject: [PATCH 416/812] Memory Calculation Headroom This change adds a configuration option that allocates empty overhead in the memory calculation. This configuration defaults to zero, but would be used in cases where the memory calculator cannot accurately allocate memory regions (e.g. 10G heap sizes). [resolves #583] --- config/open_jdk_jre.yml | 1 + config/oracle_jre.yml | 1 + config/sap_machine_jre.yml | 3 ++- config/zulu_jre.yml | 1 + docs/jre-open_jdk_jre.md | 22 ++++++++------- docs/jre-oracle_jre.md | 22 ++++++++------- docs/jre-sap_machine_jre.md | 22 ++++++++------- docs/jre-zulu_jre.md | 22 ++++++++------- .../jre/open_jdk_like_memory_calculator.rb | 10 ++++++- .../open_jdk_like_memory_calculator_spec.rb | 27 ++++++++++++++++--- spec/java_buildpack/jre/open_jdk_like_spec.rb | 4 +-- 11 files changed, 91 insertions(+), 44 deletions(-) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 963b4d02a4..dd37c71575 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -26,4 +26,5 @@ memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" class_count: + headroom: stack_threads: 250 diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index da9d5e54fe..e8250bb728 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -29,4 +29,5 @@ memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" class_count: + headroom: stack_threads: 250 diff --git a/config/sap_machine_jre.yml b/config/sap_machine_jre.yml index e583833d0e..b76c74944c 100644 --- a/config/sap_machine_jre.yml +++ b/config/sap_machine_jre.yml @@ -25,5 +25,6 @@ jvmkill_agent: memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" - class_count: + class_count: + headroom: stack_threads: 250 diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 695818d102..abd9e8f78a 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -29,4 +29,5 @@ memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" class_count: + headroom: stack_threads: 250 diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 7ec65b96b5..0cc5c6867a 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -91,6 +91,19 @@ The user can change the container's total memory available to influence the JRE Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory available results in the heap size setting increasing or decreasing by a corresponding amount. +#### Loaded Classes + +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: + +```yaml +class_count: 500 +``` + +#### Headroom + +A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. + #### Stack Threads The amount of memory that should be allocated to stacks is given as an amount of memory per @@ -102,15 +115,6 @@ the following example: stack_threads: 500 ``` -#### Loaded Classes - -The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. -If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: - -```yaml -class_count: 500 -``` - #### Java Options If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 3f4d376d53..4062f38461 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -107,6 +107,19 @@ The user can change the container's total memory available to influence the JRE Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory available results in the heap size setting increasing or decreasing by a corresponding amount. +#### Loaded Classes + +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: + +```yaml +class_count: 500 +``` + +#### Headroom + +A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. + #### Stack Threads The amount of memory that should be allocated to stacks is given as an amount of memory per @@ -118,15 +131,6 @@ the following example: stack_threads: 500 ``` -#### Loaded Classes - -The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. -If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: - -```yaml -class_count: 500 -``` - #### Java Options If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to diff --git a/docs/jre-sap_machine_jre.md b/docs/jre-sap_machine_jre.md index 6f063b8698..9e1d4ad057 100644 --- a/docs/jre-sap_machine_jre.md +++ b/docs/jre-sap_machine_jre.md @@ -94,6 +94,19 @@ The user can change the container's total memory available to influence the JRE Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory available results in the heap size setting increasing or decreasing by a corresponding amount. +#### Loaded Classes + +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: + +```yaml +class_count: 500 +``` + +#### Headroom + +A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. + #### Stack Threads The amount of memory that should be allocated to stacks is given as an amount of memory per @@ -105,15 +118,6 @@ the following example: stack_threads: 500 ``` -#### Loaded Classes - -The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. -If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: - -```yaml -class_count: 500 -``` - #### Java Options If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index d8ba2df866..d21ceeb5bd 100755 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -98,6 +98,19 @@ The user can change the container's total memory available to influence the JRE Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory available results in the heap size setting increasing or decreasing by a corresponding amount. +#### Loaded Classes + +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: + +```yaml +class_count: 500 +``` + +#### Headroom + +A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. + #### Stack Threads The amount of memory that should be allocated to stacks is given as an amount of memory per @@ -109,15 +122,6 @@ the following example: stack_threads: 500 ``` -#### Loaded Classes - -The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. -If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: - -```yaml -class_count: 500 -``` - #### Java Options If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index e424e36b95..9d7618e556 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -89,6 +89,10 @@ def class_count(configuration) configuration['class_count'] || (0.35 * actual_class_count(root)).ceil end + def headroom(configuration) + configuration['headroom'] + end + def memory_calculator @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{@version}" end @@ -101,9 +105,13 @@ def memory_calculator_tar def memory_calculation_string(relative_path) memory_calculation_string = [qualify_path(memory_calculator, relative_path)] memory_calculation_string << '-totMemory=$MEMORY_LIMIT' - memory_calculation_string << "-stackThreads=#{stack_threads @configuration}" + + headroom = headroom(@configuration) + memory_calculation_string << "-headRoom=#{headroom}" if headroom + memory_calculation_string << "-loadedClasses=#{class_count @configuration}" memory_calculation_string << "-poolType=#{pool_type}" + memory_calculation_string << "-stackThreads=#{stack_threads @configuration}" memory_calculation_string << '-vmOptions="$JAVA_OPTS"' memory_calculation_string.join(' ') diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 86d0bd9b68..6deb03b4dd 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -91,8 +91,8 @@ command = component.memory_calculation_command expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ - 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ - '-loadedClasses=2 -poolType=metaspace -vmOptions="$JAVA_OPTS") && echo JVM Memory ' \ + 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -loadedClasses=2 ' \ + '-poolType=metaspace -stackThreads=200 -vmOptions="$JAVA_OPTS") && echo JVM Memory ' \ 'Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') end @@ -111,6 +111,25 @@ expect(environment_variables).to include('MALLOC_ARENA_MAX=2') end + context 'with headroom' do + + let(:configuration) { { 'headroom' => '11', 'stack_threads' => '200' } } + + it 'creates memory calculation command with headroom', + app_fixture: 'jre_memory_calculator_application' do + + java_home.version = version_8 + + command = component.memory_calculation_command + + expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ + 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -headRoom=11 ' \ + '-loadedClasses=2 -poolType=metaspace -stackThreads=200 -vmOptions="$JAVA_OPTS") && echo ' \ + 'JVM Memory Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') + end + + end + context 'when java 9' do it 'creates memory calculation command', @@ -121,8 +140,8 @@ command = component.memory_calculation_command expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ - 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -stackThreads=200 ' \ - '-loadedClasses=14777 -poolType=metaspace -vmOptions="$JAVA_OPTS") && echo JVM Memory ' \ + 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -loadedClasses=14777 ' \ + '-poolType=metaspace -stackThreads=200 -vmOptions="$JAVA_OPTS") && echo JVM Memory ' \ 'Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') end diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index 9a88a1a20c..5d6eed5198 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -70,7 +70,7 @@ java_home.version = version_7 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ - ' -stackThreads=200 -loadedClasses=0 -poolType=permgen -vmOptions="$JAVA_OPTS")' \ + ' -loadedClasses=0 -poolType=permgen -stackThreads=200 -vmOptions="$JAVA_OPTS")' \ ' && echo JVM Memory Configuration: $CALCULATED_MEMORY && ' \ 'JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') @@ -80,7 +80,7 @@ java_home.version = version_8 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ - ' -stackThreads=200 -loadedClasses=0 -poolType=metaspace -vmOptions="$JAVA_OPTS")' \ + ' -loadedClasses=0 -poolType=metaspace -stackThreads=200 -vmOptions="$JAVA_OPTS")' \ ' && echo JVM Memory Configuration: $CALCULATED_MEMORY && ' \ 'JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') From 91bd8788ea4a2417b2868934d2bc70e3b3f9e68d Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 8 May 2018 15:14:09 -0700 Subject: [PATCH 417/812] Spring Boot Thin Launcher This change adds support for the Spring Boot Thin Launcher. It caches the application's dependencies during the compile phase and uses them at runtime. [resolves #414] --- .../component/base_component.rb | 4 ++-- lib/java_buildpack/container/java_main.rb | 17 +++++++++++++++ lib/java_buildpack/util/spring_boot_utils.rb | 21 +++++++++++++++++++ .../META-INF/MANIFEST.MF | 4 ++++ .../lib/.gitignore | 0 .../container/java_main_spec.rb | 18 ++++++++++++++++ .../util/spring_boot_utils_spec.rb | 15 +++++++++++++ 7 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/container_main_spring_boot_thin_launcher/META-INF/MANIFEST.MF create mode 100644 spec/fixtures/container_main_spring_boot_thin_launcher/lib/.gitignore diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 6b18e71e41..a7e2d2396f 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -169,9 +169,9 @@ def download_zip(version, uri, strip_top_level = true, target_directory = @dropl # # @param [String] caption the caption to print when timing starts # @return [Void] - def with_timing(caption) + def with_timing(caption, include_arrow = false) start_time = Time.now - print " #{caption} " + print "#{include_arrow ? '----->'.red.bold : ' '} #{caption} " yield diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index f179f9c6a3..b1d8df8648 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -47,6 +47,13 @@ def detect # (see JavaBuildpack::Component::BaseComponent#compile) def compile return unless @spring_boot_utils.is?(@application) + + if @spring_boot_utils.thin?(@application) + with_timing 'Caching Spring Boot Thin Launcher Dependencies', true do + @spring_boot_utils.cache_thin_dependencies @droplet.java_home.root, @application.root, thin_root + end + end + @droplet.additional_libraries.link_to(@spring_boot_utils.lib(@droplet)) end @@ -56,6 +63,12 @@ def release if @spring_boot_utils.is?(@application) @droplet.environment_variables.add_environment_variable 'SERVER_PORT', '$PORT' + + if @spring_boot_utils.thin?(@application) + @droplet.java_opts + .add_system_property('thin.offline', true) + .add_system_property('thin.root', thin_root) + end else @droplet.additional_libraries.insert 0, @application.root end @@ -98,6 +111,10 @@ def manifest_class_path values.nil? ? [] : values.split(' ').map { |value| @droplet.root + value } end + def thin_root + @droplet.sandbox + 'repository' + end + end end diff --git a/lib/java_buildpack/util/spring_boot_utils.rb b/lib/java_buildpack/util/spring_boot_utils.rb index 91276a310b..52bde420a9 100644 --- a/lib/java_buildpack/util/spring_boot_utils.rb +++ b/lib/java_buildpack/util/spring_boot_utils.rb @@ -19,17 +19,28 @@ require 'java_buildpack/util' require 'java_buildpack/util/jar_finder' require 'java_buildpack/util/java_main_utils' +require 'java_buildpack/util/shell' module JavaBuildpack module Util # Utilities for dealing with Spring Boot applications class SpringBootUtils + include JavaBuildpack::Util::Shell def initialize @jar_finder = JavaBuildpack::Util::JarFinder.new(/.*spring-boot-([\d].*)\.jar/) end + # Caches the dependencies of a Thin Launcher application by execute the application with +dryRun+ + # + # @param [Pathname] java_home the Java home to find +java+ in + # @param [Pathname] application_root the root of the application to run + # @param [Pathname] thin_root the root to cache cache dependencies at + def cache_thin_dependencies(java_home, application_root, thin_root) + shell "#{java_home + 'bin/java'} -Dthin.dryrun -Dthin.root=#{thin_root} -cp #{application_root} #{THIN_WRAPPER}" + end + # Indicates whether an application is a Spring Boot application # # @param [Application] application the application to search @@ -39,6 +50,14 @@ def is?(application) @jar_finder.is?(application) end + # Indicates whether an application is a Spring Boot Thin Launcher application + # + # @param [Application] application the application to search + # @return [Boolean] +true+ if the application is a Spring Boot Thin Launcher application, +false+ otherwise + def thin?(application) + THIN_WRAPPER == JavaBuildpack::Util::JavaMainUtils.main_class(application) + end + # The lib directory of Spring Boot used by the application # # @param [Droplet] droplet the droplet to search @@ -74,6 +93,8 @@ def version(application) SPRING_BOOT_VERSION = 'Spring-Boot-Version' + THIN_WRAPPER = 'org.springframework.boot.loader.wrapper.ThinJarWrapper' + private_constant :SPRING_BOOT_LIB, :SPRING_BOOT_VERSION def boot_inf_lib_dir(droplet) diff --git a/spec/fixtures/container_main_spring_boot_thin_launcher/META-INF/MANIFEST.MF b/spec/fixtures/container_main_spring_boot_thin_launcher/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..33dde1d32b --- /dev/null +++ b/spec/fixtures/container_main_spring_boot_thin_launcher/META-INF/MANIFEST.MF @@ -0,0 +1,4 @@ +Spring-Boot-Lib: manifest-lib-value/ +Spring-Boot-Version: 1.2.5.RELEASE +Main-Class: org.springframework.boot.loader.wrapper.ThinJarWrapper + diff --git a/spec/fixtures/container_main_spring_boot_thin_launcher/lib/.gitignore b/spec/fixtures/container_main_spring_boot_thin_launcher/lib/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index 56cc3af543..43252bc529 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -73,6 +73,15 @@ expect(test_jar2.readlink).to eq((additional_libs_directory + 'test-jar-2.jar').relative_path_from(lib)) end + it 'caches Spring Boot Thin Launcher dependencies', + app_fixture: 'container_main_spring_boot_thin_launcher' do + + expect_any_instance_of(JavaBuildpack::Util::SpringBootUtils).to receive(:cache_thin_dependencies) + .with(java_home.root, application.root, sandbox + 'repository') + + component.compile + end + context do include_context 'with explicit main class' @@ -131,4 +140,13 @@ '-cp $PWD/. org.springframework.boot.loader.PropertiesLauncher') end + it 'releases Spring Boot thin applications by specifying thin.root', + app_fixture: 'container_main_spring_boot_thin_launcher' do + + component.release + + expect(java_opts).to include('-Dthin.offline=true') + expect(java_opts).to include('-Dthin.root=$PWD/.java-buildpack/java_main/repository') + end + end diff --git a/spec/java_buildpack/util/spring_boot_utils_spec.rb b/spec/java_buildpack/util/spring_boot_utils_spec.rb index ef299c9b0d..32b92ababb 100644 --- a/spec/java_buildpack/util/spring_boot_utils_spec.rb +++ b/spec/java_buildpack/util/spring_boot_utils_spec.rb @@ -48,6 +48,12 @@ expect(utils.is?(application)).not_to be end + it 'determines if an application is a thin application', + app_fixture: 'container_main_spring_boot_thin_launcher' do + + expect(utils.thin?(application)).to be + end + it 'determines the version of a dist Spring Boot application', app_fixture: 'container_spring_boot_dist' do @@ -96,4 +102,13 @@ expect { utils.lib(droplet) }.to raise_error end + it 'caches thin dependencies' do + allow(utils).to receive(:shell) + + utils.cache_thin_dependencies java_home.root, 'test-application-root', 'test-thin-root' + + expect(utils).to have_received(:shell).with("#{java_home.root + 'bin/java'} -Dthin.dryrun " \ + '-Dthin.root=test-thin-root -cp test-application-root org.springframework.boot.loader.wrapper.ThinJarWrapper') + end + end From e6cb2dfe0d72552924652621f45157e6beb0acdd Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 20 Apr 2018 15:15:45 -0700 Subject: [PATCH 418/812] Introscope Property Names This change updates the preferred Introscope property names to match the internal naming scheme. It keeps the older property names around but deprecates them. [resolves #582] --- docs/framework-introscope_agent.md | 6 +- .../framework/introscope_agent.rb | 19 +-- .../framework/introscope_agent_spec.rb | 123 +++++++++++++++++- 3 files changed, 136 insertions(+), 12 deletions(-) diff --git a/docs/framework-introscope_agent.md b/docs/framework-introscope_agent.md index de0653f61f..d1a401680b 100644 --- a/docs/framework-introscope_agent.md +++ b/docs/framework-introscope_agent.md @@ -23,9 +23,11 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- +| `agent_manager_credential` | (Optional) The credential that is used to connect to the Enterprise Manager server +| `agent_manager_url` | The url of the Enterprise Manager server | `agent_name` | (Optional) The name that should be given to this instance of the Introscope agent -| `credential`| (Optional) The credential that is used to connect to the Enterprise Manager server -| `url` | The url of the Introscope Enterprise Manager server +| `credential`| (Deprecated) The credential that is used to connect to the Enterprise Manager server +| `url` | (Deprecated) The url of the Enterprise Manager server To provide more complex values such as the `agent_name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `agent_name` could be set with a value of `agent-$(expr "$VCAP_APPLICATION" : '.*application_name[": ]*\([[:word:]]*\).*')` to calculate a value from the Cloud Foundry application name. diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index d04bc6246c..33dfcaca6f 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -34,7 +34,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, 'url')['credentials'] + credentials = @application.services.find_service(FILTER, %w[agent_manager_url url])['credentials'] java_opts = @droplet.java_opts java_opts @@ -44,7 +44,10 @@ def release .add_system_property('com.wily.introscope.agent.agentName', agent_name(credentials)) .add_system_property('introscope.agent.defaultProcessName', default_process_name) - java_opts.add_system_property('agentManager.credential', credential(credentials)) if credential(credentials) + if agent_manager_credential(credentials) + java_opts.add_system_property('agentManager.credential', agent_manager_credential(credentials)) + end + add_url(credentials, java_opts) end @@ -52,7 +55,7 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, 'url' + @application.services.one_service? FILTER, %w[agent_manager_url url] end private @@ -70,7 +73,7 @@ def agent_jar end def add_url(credentials, java_opts) - agent_manager = url(credentials) + agent_manager = agent_manager_url(credentials) host, port, socket_factory = parse_url(agent_manager) java_opts.add_system_property('agentManager.url.1', agent_manager) @@ -117,12 +120,12 @@ def protocol_mapping(protocol) protocol_socket_factory[protocol] || protocol end - def url(credentials) - credentials['url'] + def agent_manager_url(credentials) + credentials['agent_manager_url'] || credentials['url'] end - def credential(credentials) - credentials['credential'] + def agent_manager_credential(credentials) + credentials['agent_manager_credential'] || credentials['credential'] end end end diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index fc9570a937..e235078223 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -40,7 +40,7 @@ let(:credentials) { {} } before do - allow(services).to receive(:one_service?).with(/introscope/, 'url').and_return(true) + allow(services).to receive(:one_service?).with(/introscope/, %w[agent_manager_url url]).and_return(true) allow(services).to receive(:find_service).and_return('credentials' => credentials) end @@ -89,6 +89,30 @@ end end + context do + + let(:credentials) { { 'agent_manager_url' => 'test-host-name:5001' } } + + it 'parses the agent_manager_url and sets host port and default socket factory' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + + expect(java_opts).to include('-DagentManager.url.1=test-host-name:5001') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=5001') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.DefaultSocketFactory') + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + end + end + context do let(:credentials) { { 'url' => 'ssl://test-host-name:5443' } } @@ -112,6 +136,29 @@ end end + context do + let(:credentials) { { 'agent_manager_url' => 'ssl://test-host-name:5443' } } + + it 'parses the agent_manager_url and sets host, port, and ssl socket factory' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + + expect(java_opts).to include('-DagentManager.url.1=ssl://test-host-name:5443') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=5443') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + end + end + context do let(:credentials) { { 'url' => 'http://test-host-name:8081' } } @@ -135,6 +182,29 @@ end end + context do + let(:credentials) { { 'agent_manager_url' => 'http://test-host-name:8081' } } + + it 'parses the agent_manager_url and sets host, port, and http socket factory' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + + expect(java_opts).to include('-DagentManager.url.1=http://test-host-name:8081') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=8081') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.HttpTunnelingSocketFactory') + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + end + end + context do let(:credentials) { { 'url' => 'https://test-host-name:8444' } } @@ -158,10 +228,33 @@ end end + context do + let(:credentials) { { 'agent_manager_url' => 'https://test-host-name:8444' } } + + it 'parses the agent_manager_url and sets host, port, and https socket factory' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + + expect(java_opts).to include('-DagentManager.url.1=https://test-host-name:8444') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=8444') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + end + end + context do let(:credentials) { { 'url' => 'https://test-host-name:8444', 'credential' => 'test-credential-cccf-88-ae' } } - it 'sets the url and also the agent manager credential' do + it 'sets the url and also the credential' do component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') @@ -179,7 +272,33 @@ expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') expect(java_opts).to include('-DagentManager.credential=test-credential-cccf-88-ae') + end + end + + context do + let(:credentials) do + { 'agent_manager_url' => 'https://test-host-name:8444', + 'agent_manager_credential' => 'test-credential-cccf-88-ae' } + end + + it 'sets the agent_manager_url and also the agent_manager_credential' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=test-application-name') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + expect(java_opts).to include('-DagentManager.url.1=https://test-host-name:8444') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=8444') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + expect(java_opts).to include('-DagentManager.credential=test-credential-cccf-88-ae') end end From 25a0be90b7e7284ed754d48ecc0a3214e0769e2d Mon Sep 17 00:00:00 2001 From: Arghya Sadhu Date: Fri, 11 May 2018 19:17:37 +0530 Subject: [PATCH 419/812] Remove Incorrect Documentation Previously the JAVA_OPTS documentation mentioned an exclusion of any memory configuration flags. This exclusion was dropped in v4.0 and was never removed. This change removes that out of date documentation. [resolves #592] --- docs/framework-java_opts.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/framework-java_opts.md b/docs/framework-java_opts.md index 5f03b83977..69dea716d6 100644 --- a/docs/framework-java_opts.md +++ b/docs/framework-java_opts.md @@ -24,8 +24,6 @@ The framework can be configured by creating or modifying the [`config/java_opts. | `from_environment` | Whether to append the value of the `JAVA_OPTS` environment variable to the collection of Java options | `java_opts` | The Java options to use when running the application. All values are used without modification when invoking the JVM. The options are specified as a single YAML scalar in plain style or enclosed in single or double quotes. -Any `JAVA_OPTS` from either the config file or environment variables that configure memory options will cause deployment to fail as they're not allowed. Memory options are configured by the buildpack and may not be modified. - Any `JAVA_OPTS` from either the config file or environment variables will be specified in the start command after any Java Opts added by other frameworks. ## Escaping strings From 1c28d95eb8b2d25bdde5bd66f81839fddbfd55ae Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 11 May 2018 15:01:29 -0700 Subject: [PATCH 420/812] New YourKit major version --- config/your_kit_profiler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml index 736a588c2d..bee70b530f 100644 --- a/config/your_kit_profiler.yml +++ b/config/your_kit_profiler.yml @@ -15,7 +15,7 @@ # JMX configuration --- -version: 2017.+ +version: 2018.+ repository_root: https://download.run.pivotal.io/your-kit/{platform}/{architecture} enabled: false port: 10001 From 0ba3b16cc4fc4ed29fb22854e4e26dece1f767c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=AFd=20Ibrihen?= Date: Thu, 31 May 2018 16:17:33 +0200 Subject: [PATCH 421/812] Documentation Polishing [resolves #596] --- docs/framework-jmx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-jmx.md b/docs/framework-jmx.md index 64fd147e7e..8d122ccca8 100644 --- a/docs/framework-jmx.md +++ b/docs/framework-jmx.md @@ -30,7 +30,7 @@ After starting an application with JMX enabled, an SSH tunnel must be created to $ cf ssh -N -T -L :localhost: ``` -The `REMOTE_PORT` should match the `port` configuration for the application (`5000` by default). The `LOCAL_PORT` must matche the `REMOTE_PORT`. +The `REMOTE_PORT` should match the `port` configuration for the application (`5000` by default). The `LOCAL_PORT` must match the `REMOTE_PORT`. Once the SSH tunnel has been created, your JConsole should connect to `localhost:` for JMX access. From 98580a4bfcb0338d678d2c59acddfe56ebc3c8d8 Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Wed, 13 Jun 2018 13:04:35 +0200 Subject: [PATCH 422/812] removed explicit HOST_ID setting --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 13 +------------ .../framework/dynatrace_one_agent_spec.rb | 5 +---- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 7c0a96cb67..6719b88269 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -86,8 +86,6 @@ def supports? DT_CONNECTION_POINT = 'DT_CONNECTION_POINT' - DT_HOST_ID = 'DT_HOST_ID' - DT_TENANT = 'DT_TENANT' DT_TENANTTOKEN = 'DT_TENANTTOKEN' @@ -98,7 +96,7 @@ def supports? SKIP_ERRORS = 'skiperrors' - private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_HOST_ID, :DT_TENANT, + private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_TENANT, :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :SKIP_ERRORS def agent_download_url @@ -143,7 +141,6 @@ def dynatrace_environment_variables(manifest) .add_environment_variable(DT_CONNECTION_POINT, endpoints(manifest)) environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) unless application_id? - environment_variables.add_environment_variable(DT_HOST_ID, host_id) unless host_id? end def endpoints(manifest) @@ -164,14 +161,6 @@ def expand(file) end end - def host_id - "#{@application.details['application_name']}_${CF_INSTANCE_INDEX}" - end - - def host_id? - @application.environment.key?(DT_HOST_ID) - end - def skip_errors? credentials[SKIP_ERRORS].to_b end diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 737652138d..c21d60b044 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -69,7 +69,6 @@ component.release expect(environment_variables).to include('DT_APPLICATIONID=test-application-name') - expect(environment_variables).to include('DT_HOST_ID=test-application-name_${CF_INSTANCE_INDEX}') expect(environment_variables).to include('DT_TENANT=test-environmentid') expect(environment_variables).to include('DT_TENANTTOKEN=token-from-file') expect(environment_variables).to include('DT_CONNECTION_POINT=' \ @@ -79,8 +78,7 @@ context do let(:environment) do - { 'DT_APPLICATIONID' => 'test-application-id', - 'DT_HOST_ID' => 'test-host-id' } + { 'DT_APPLICATIONID' => 'test-application-id' } end it 'does not update environment variables if they exist', @@ -89,7 +87,6 @@ component.release expect(environment_variables).not_to include(/DT_APPLICATIONID/) - expect(environment_variables).not_to include(/DT_HOST_ID/) end end From d5bad1b385630c0faea82749e33a3e669a75c78e Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Wed, 13 Jun 2018 13:04:35 +0200 Subject: [PATCH 423/812] Remove Explicit HOST_ID This change removes the ability to explicitly set the HOST_ID in the environment. [resolves #600] --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 13 +------------ .../framework/dynatrace_one_agent_spec.rb | 5 +---- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 7c0a96cb67..6719b88269 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -86,8 +86,6 @@ def supports? DT_CONNECTION_POINT = 'DT_CONNECTION_POINT' - DT_HOST_ID = 'DT_HOST_ID' - DT_TENANT = 'DT_TENANT' DT_TENANTTOKEN = 'DT_TENANTTOKEN' @@ -98,7 +96,7 @@ def supports? SKIP_ERRORS = 'skiperrors' - private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_HOST_ID, :DT_TENANT, + private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_TENANT, :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :SKIP_ERRORS def agent_download_url @@ -143,7 +141,6 @@ def dynatrace_environment_variables(manifest) .add_environment_variable(DT_CONNECTION_POINT, endpoints(manifest)) environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) unless application_id? - environment_variables.add_environment_variable(DT_HOST_ID, host_id) unless host_id? end def endpoints(manifest) @@ -164,14 +161,6 @@ def expand(file) end end - def host_id - "#{@application.details['application_name']}_${CF_INSTANCE_INDEX}" - end - - def host_id? - @application.environment.key?(DT_HOST_ID) - end - def skip_errors? credentials[SKIP_ERRORS].to_b end diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 737652138d..c21d60b044 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -69,7 +69,6 @@ component.release expect(environment_variables).to include('DT_APPLICATIONID=test-application-name') - expect(environment_variables).to include('DT_HOST_ID=test-application-name_${CF_INSTANCE_INDEX}') expect(environment_variables).to include('DT_TENANT=test-environmentid') expect(environment_variables).to include('DT_TENANTTOKEN=token-from-file') expect(environment_variables).to include('DT_CONNECTION_POINT=' \ @@ -79,8 +78,7 @@ context do let(:environment) do - { 'DT_APPLICATIONID' => 'test-application-id', - 'DT_HOST_ID' => 'test-host-id' } + { 'DT_APPLICATIONID' => 'test-application-id' } end it 'does not update environment variables if they exist', @@ -89,7 +87,6 @@ component.release expect(environment_variables).not_to include(/DT_APPLICATIONID/) - expect(environment_variables).not_to include(/DT_HOST_ID/) end end From d9ad1fbba22607b13fa4dd8a3d26eb019e5f5914 Mon Sep 17 00:00:00 2001 From: Dhruv Mevada Date: Fri, 15 Jun 2018 14:21:51 -0700 Subject: [PATCH 424/812] Allow Credentials to Configure Default Process Name Previously, introscope.agent.defaultProcessName was always set with the name of the running application. This change allows a parameter to be set in the credentials payload that will override that value. [resolves #602] --- docs/framework-introscope_agent.md | 1 + .../framework/introscope_agent.rb | 6 ++-- .../framework/introscope_agent_spec.rb | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/docs/framework-introscope_agent.md b/docs/framework-introscope_agent.md index d1a401680b..fa785267da 100644 --- a/docs/framework-introscope_agent.md +++ b/docs/framework-introscope_agent.md @@ -23,6 +23,7 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- +|`agent_defaultProcessName`| (Optional) The name that is specified for the agent process. If not specified, default value is the application name. | `agent_manager_credential` | (Optional) The credential that is used to connect to the Enterprise Manager server | `agent_manager_url` | The url of the Enterprise Manager server | `agent_name` | (Optional) The name that should be given to this instance of the Introscope agent diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index 33dfcaca6f..69a36f71d0 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -42,7 +42,7 @@ def release .add_system_property('com.wily.introscope.agentProfile', agent_profile) .add_system_property('introscope.agent.hostName', agent_host_name) .add_system_property('com.wily.introscope.agent.agentName', agent_name(credentials)) - .add_system_property('introscope.agent.defaultProcessName', default_process_name) + .add_system_property('introscope.agent.defaultProcessName', default_process_name(credentials)) if agent_manager_credential(credentials) java_opts.add_system_property('agentManager.credential', agent_manager_credential(credentials)) @@ -103,8 +103,8 @@ def agent_profile @droplet.sandbox + 'core/config/IntroscopeAgent.profile' end - def default_process_name - @application.details['application_name'] + def default_process_name(credentials) + credentials['agent_defaultProcessName'] || @application.details['application_name'] end def protocol_mapping(protocol) diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index e235078223..9c299726d9 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -302,5 +302,33 @@ end end + context do + let(:credentials) do + { 'agent_manager_url' => 'https://test-host-name:8444', + 'agent_manager_credential' => 'test-credential-cccf-88-ae', + 'agent_defaultProcessName' => 'TestProcess'} + end + + it 'sets the agent_manager_url, agent_manager_credential, and agent_process_name' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/introscope_agent/Agent.jar') + expect(java_opts).to include('-Dcom.wily.introscope.agentProfile=$PWD/.java-buildpack/introscope_agent/core' \ + '/config/IntroscopeAgent.profile') + expect(java_opts).to include('-Dintroscope.agent.defaultProcessName=TestProcess') + expect(java_opts).to include('-Dintroscope.agent.hostName=test-application-uri-0') + + expect(java_opts).to include('-DagentManager.url.1=https://test-host-name:8444') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=8444') + expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ + 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') + + expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + expect(java_opts).to include('-DagentManager.credential=test-credential-cccf-88-ae') + end + end + end end From bd49c03c3f29423c65e0271f21659d83450da3f7 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 19 Jun 2018 07:09:44 -0700 Subject: [PATCH 425/812] Polishing --- spec/java_buildpack/framework/introscope_agent_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index 9c299726d9..586ada5135 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -306,7 +306,7 @@ let(:credentials) do { 'agent_manager_url' => 'https://test-host-name:8444', 'agent_manager_credential' => 'test-credential-cccf-88-ae', - 'agent_defaultProcessName' => 'TestProcess'} + 'agent_defaultProcessName' => 'TestProcess' } end it 'sets the agent_manager_url, agent_manager_credential, and agent_process_name' do From 695c87b27855f7fd995ad5c32b05da8373a125dd Mon Sep 17 00:00:00 2001 From: Dhruv Mevada Date: Tue, 19 Jun 2018 15:00:17 -0700 Subject: [PATCH 426/812] Update Default Process Name This change updates the Default Process Name property to be consistent with its peer properties. [resolves #603] --- docs/framework-introscope_agent.md | 2 +- lib/java_buildpack/framework/introscope_agent.rb | 2 +- spec/java_buildpack/framework/introscope_agent_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/framework-introscope_agent.md b/docs/framework-introscope_agent.md index fa785267da..5e92103e78 100644 --- a/docs/framework-introscope_agent.md +++ b/docs/framework-introscope_agent.md @@ -23,7 +23,7 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- -|`agent_defaultProcessName`| (Optional) The name that is specified for the agent process. If not specified, default value is the application name. +|`agent_default_process_name`| (Optional) The name that is specified for the agent process. If not specified, default value is the application name. | `agent_manager_credential` | (Optional) The credential that is used to connect to the Enterprise Manager server | `agent_manager_url` | The url of the Enterprise Manager server | `agent_name` | (Optional) The name that should be given to this instance of the Introscope agent diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index 69a36f71d0..c1d92d9703 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -104,7 +104,7 @@ def agent_profile end def default_process_name(credentials) - credentials['agent_defaultProcessName'] || @application.details['application_name'] + credentials['agent_default_process_name'] || @application.details['application_name'] end def protocol_mapping(protocol) diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index 586ada5135..3d78786422 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -306,7 +306,7 @@ let(:credentials) do { 'agent_manager_url' => 'https://test-host-name:8444', 'agent_manager_credential' => 'test-credential-cccf-88-ae', - 'agent_defaultProcessName' => 'TestProcess' } + 'agent_default_process_name' => 'TestProcess' } end it 'sets the agent_manager_url, agent_manager_credential, and agent_process_name' do From c0c11c747fffa1124d309838e4ec8f04dfdf92b6 Mon Sep 17 00:00:00 2001 From: Pavan Krishna Date: Mon, 25 Jun 2018 11:32:49 -0700 Subject: [PATCH 427/812] AppDynamics Instance Index This change updates the AppDynamics configuration to extract the instance index from the CF_INSTANCE_INDEX environment variable. [resolves #606] --- config/app_dynamics_agent.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index e2d170c8c4..dc724ad3c9 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -20,5 +20,5 @@ repository_root: https://packages.appdynamics.com/java default_application_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); puts \"#{a['space_name']}:#{a['application_name']}\"") default_node_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); - puts \"#{a['application_name']}:#{a['instance_index']}\"") -default_tier_name: + puts \"#{a['application_name']}:#{ENV['CF_INSTANCE_INDEX']}\"") +default_tier_name: From cf538e072ae2e978bdfe550a780f45505b9c4f94 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 9 Jul 2018 11:10:36 -0700 Subject: [PATCH 428/812] Replace Ruby JSON parsing with jq This change updates the handful of configurations that started Ruby to parse JSON at runtime to use the jq utility instead. This is much lower impact at startup with the added advantage of being easier to understand. --- config/app_dynamics_agent.yml | 6 ++---- config/introscope_agent.yml | 4 ++-- config/sky_walking_agent.yml | 3 +-- config/your_kit_profiler.yml | 3 +-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index dc724ad3c9..b4567afd22 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -17,8 +17,6 @@ --- version: 4.+ repository_root: https://packages.appdynamics.com/java -default_application_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); - puts \"#{a['space_name']}:#{a['application_name']}\"") -default_node_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); - puts \"#{a['application_name']}:#{ENV['CF_INSTANCE_INDEX']}\"") +default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name") +default_node_name: $(jq -r -n "$VCAP_APPLICATION | .application_name + \":$CF_INSTANCE_INDEX\"") default_tier_name: diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index 885424bbf3..1ec08affe3 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -15,6 +15,6 @@ # Configuration for the CA Wily framework --- -repository_root: https://ca.bintray.com/apm-agents version: 10.+ -default_agent_name: $(ruby -e "require 'json' ; puts JSON.parse(ENV['VCAP_APPLICATION'])['application_name']") +repository_root: https://ca.bintray.com/apm-agents +default_agent_name: $(jq -r -n "$VCAP_APPLICATION | .application_name") diff --git a/config/sky_walking_agent.yml b/config/sky_walking_agent.yml index 0dbbb57fb4..b85bfce02a 100644 --- a/config/sky_walking_agent.yml +++ b/config/sky_walking_agent.yml @@ -18,6 +18,5 @@ # avoid conflicts. --- version: 3.+ -default_application_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); - puts \"#{a['space_name']}:#{a['application_name']}\"") repository_root: https://java-buildpack.cloudfoundry.org/sky-walking +default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name") diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml index bee70b530f..eb8ecb65a8 100644 --- a/config/your_kit_profiler.yml +++ b/config/your_kit_profiler.yml @@ -19,5 +19,4 @@ version: 2018.+ repository_root: https://download.run.pivotal.io/your-kit/{platform}/{architecture} enabled: false port: 10001 -default_session_name: $(ruby -e "require 'json' ; a = JSON.parse(ENV['VCAP_APPLICATION']); - puts \"#{a['application_name']}:#{a['instance_index']}\"") +default_session_name: $(jq -r -n "$VCAP_APPLICATION | .application_name + \":$CF_INSTANCE_INDEX\"") From ce0c64d5b6578dd3e47d17cab4d2dfb234bfba79 Mon Sep 17 00:00:00 2001 From: Fan W Date: Wed, 20 Jun 2018 14:59:25 -0400 Subject: [PATCH 429/812] Riverbed AppInternals This change adds support for the Riverbed AppInterals agent to the buildpack. [#605] --- config/components.yml | 1 + config/riverbed_appinternals_agent.yml | 20 +++ docs/framework-riverbed_appinternals_agent.md | 49 +++++++ .../framework/riverbed_appinternals_agent.rb | 138 ++++++++++++++++++ rakelib/versions_task.rb | 1 + .../stub-riverbed-appinternals-agent.zip | Bin 0 -> 2244 bytes .../riverbed_appinternals_agent_spec.rb | 106 ++++++++++++++ 7 files changed, 315 insertions(+) create mode 100644 config/riverbed_appinternals_agent.yml create mode 100644 docs/framework-riverbed_appinternals_agent.md create mode 100644 lib/java_buildpack/framework/riverbed_appinternals_agent.rb create mode 100644 spec/fixtures/stub-riverbed-appinternals-agent.zip create mode 100644 spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb diff --git a/config/components.yml b/config/components.yml index 29dd3a9325..546f80aa48 100644 --- a/config/components.yml +++ b/config/components.yml @@ -62,6 +62,7 @@ frameworks: - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::ProtectAppSecurityProvider" + - "JavaBuildpack::Framework::RiverbedAppinternalsAgent" - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::SkyWalkingAgent" diff --git a/config/riverbed_appinternals_agent.yml b/config/riverbed_appinternals_agent.yml new file mode 100644 index 0000000000..135ed49683 --- /dev/null +++ b/config/riverbed_appinternals_agent.yml @@ -0,0 +1,20 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the riverbed appinternals agent framework +--- +version: 10.+ +repository_root: https://pcf-instrumentation-download.steelcentral.net/ +rvbd_moniker: $(jq -r -n "$VCAP_APPLICATION | .application_name") diff --git a/docs/framework-riverbed_appinternals_agent.md b/docs/framework-riverbed_appinternals_agent.md new file mode 100644 index 0000000000..6b551a04f9 --- /dev/null +++ b/docs/framework-riverbed_appinternals_agent.md @@ -0,0 +1,49 @@ +# Riverbed Appinternals Agent Framework +The Riverbed Appinternals Agent Framework causes an application to be bound with a Riverbed Appinternals service instance. + + + + + + + + + +
Detection CriterionExistence of a single bound Riverbed Appinternals agent service. The existence of an agent service is defined by the VCAP_SERVICES payload containing a service name, label or tag with appinternals as a substring (the substring is case insensitive). +
Tagsriverbed-appinternals-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +When binding Appinternals using a user-provided service, it must have appinternals as substring. The credential payload can contain the following entries: + +| Name | Description +| ---- | ----------- +| `rvbd_dsa_port` | (Optional)The AppInternals agent (DSA) port (default 2111). +| `rvbd_agent_port` | (Optional) The AppInternals agent socket port (default 7073). +| `rvbd_moniker` | (Optional) A custom name for the application (default supplied by agent process discovery). + +**NOTE** + +Change `rvbd_dsa_port` and `rvbd_agent_port` only if there is a port conflict + +### Example: Creating Riverbed Appinternals User-Provided Service Payload + +``` +cf cups spring-music-appinternals -p '{"rvbd_dsa_port":"9999","rvbd_moniker":"my_app"}' +cf bind-service spring-music spring-music-appinternals +``` + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/riverbed_appinternals_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Riverbed Appinternals agent repository index ([details][repositories]). +| `version` | The version of the Riverbed Appinternals agent to use. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering +[`config/riverbed_appinternals_agent.yml`]: ../config/riverbed_appinternals_agent.yml diff --git a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb new file mode 100644 index 0000000000..06956c2368 --- /dev/null +++ b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +module JavaBuildpack + module Framework + + # Encapsulates the functionality for running the Riverbed Appinternals Agent support. + class RiverbedAppinternalsAgent < JavaBuildpack::Component::VersionedDependencyComponent + # jbp constants + FILTER = /(?i)appinternals/ + + # credentials key + RVBD_DSA_PORT = 'rvbd_dsa_port' + RVBD_AGENT_PORT = 'rvbd_agent_port' + + # javaagent args + RVBD_MONIKER = 'rvbd_moniker' + + # env + AIX_INSTRUMENT_ALL = 'AIX_INSTRUMENT_ALL' + RVBD_AGENT_FILES = 'RVBD_AGENT_FILES' + DSA_PORT = 'DSA_PORT' + RVBD_JBP_VERSION = 'RVBD_JBP_VERSION' + + # constants + DSA_PORT_DEFAULT = 2111 + RVBD_AGENT_PORT_DEFAULT = 7073 + + private_constant :FILTER, :RVBD_AGENT_PORT, + :DSA_PORT, + :RVBD_MONIKER, + :AIX_INSTRUMENT_ALL, + :RVBD_AGENT_FILES, + :DSA_PORT_DEFAULT, + :RVBD_AGENT_PORT_DEFAULT, + :RVBD_DSA_PORT, + :RVBD_JBP_VERSION + + attr_reader :version + + def initialize(context) + super(context) + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger RiverbedAppinternalsAgent + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_zip(false, @droplet.sandbox, @component_name) + `echo "#{@version} is downloaded....\n" >> /#{@droplet.sandbox}/staging.log` + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + credentials = @application.services.find_service(FILTER)['credentials'] + setup_env credentials + setup_javaopts credentials + end + + def supports? + @application.services.one_service?(FILTER) && os.casecmp('Linux').zero? + end + + private + + def setup_javaopts(credentials) + @droplet.java_opts.add_agentpath(agent_path) + rvbd_moniker = get_val_in_cred(RVBD_MONIKER, credentials[RVBD_MONIKER], nil, true) \ + || @configuration[RVBD_MONIKER] + @droplet.java_opts.add_system_property('riverbed.moniker', rvbd_moniker) unless rvbd_moniker.nil? + end + + def get_val_in_cred(property, cred_val, default, logging) + @logger.debug { "picks up credential #{property}:#{cred_val}" } if cred_val && logging + cred_val ? cred_val : default + end + + def setup_env(credentials) + @droplet.environment_variables + .add_environment_variable(DSA_PORT.upcase, get_val_in_cred(RVBD_DSA_PORT, \ + credentials[RVBD_DSA_PORT], \ + DSA_PORT_DEFAULT, true)) + .add_environment_variable(RVBD_AGENT_PORT.upcase, get_val_in_cred(RVBD_AGENT_PORT.upcase, \ + credentials[RVBD_AGENT_PORT], \ + RVBD_AGENT_PORT_DEFAULT, true)) + .add_environment_variable(AIX_INSTRUMENT_ALL, 1) + .add_environment_variable(RVBD_AGENT_FILES, 1) + .add_environment_variable(RVBD_JBP_VERSION, version) + end + + def architecture + `uname -m`.strip + end + + def os + `uname`.strip + end + + def agent_path + lib_dir + lib_ripl_name + end + + def agent_dir + @droplet.sandbox + 'agent' + end + + def lib_dir + agent_dir + 'lib' + end + + def classes_dir + agent_dir + 'classes' + end + + def lib_ripl_name + architecture == 'x86_64' || architecture == 'i686' ? 'librpilj64.so' : 'librpilj.so' + end + + end + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 01db5ff3ad..0c75e6d1e0 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -80,6 +80,7 @@ def initialize 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', 'redis_store' => 'Redis Session Store', + 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', 'sky_walking_agent' => 'SkyWalking', 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', 'spring_boot_cli' => 'Spring Boot CLI', diff --git a/spec/fixtures/stub-riverbed-appinternals-agent.zip b/spec/fixtures/stub-riverbed-appinternals-agent.zip new file mode 100644 index 0000000000000000000000000000000000000000..24e85d6504cd055dd26405427af1911231ce4d3f GIT binary patch literal 2244 zcmb7`yGjE=6ow}z3Mz^LMa4vrq_B#OSQ`+*OA$~}w_D>XD~k!6gt(<(;e+TiSlft& zSa?CKw6qZ`OTlw?Gxr&T2`8k;e&@_TGasp}r85HrU*9{+>+zS)M<2-%_s~0T&TVb> zll1*VdI2N z)%1hXksHPfMkC6WN1@iyCelZ5gJxi~$Ocw&(8+3b$jbs^$kRJ}%Dc-`&PoRmmtpvqF|-a%Iiof|X1wRB*Dfd)po@FnPa5gX)t#9$yC zE*n4_MZ?jmAF?bR%si0LOgw-!YQc^zGAu@NWx^UI)V-6gATgV [{ 'name' => 'appinternals_test_service', 'label' => 'test-service-n/a',\ + 'tags' => ['test-service-tag'], 'plan' => 'test-plan',\ + 'credentials' => { 'uri' => 'test-uri' } }] } + end + + it 'supports riverbed-appinternals-agent service' do + expect(component.supports?).to be true + end + + it 'detects with riverbed-appinternals-agent service' do + expect(component.detect).to eq("riverbed-appinternals-agent=#{version}") + end + context do + it 'unzip riverbed appinternals agent zip file', + cache_fixture: 'stub-riverbed-appinternals-agent.zip' do + + component.compile + + expect(sandbox + 'agent/lib/libAwProfile64.so').to exist + expect(sandbox + 'agent/lib/libAwProfile.so').to exist + expect(sandbox + 'agent/lib/librpilj.so').to exist + expect(sandbox + 'agent/lib/librpilj64.so').to exist + expect(sandbox + 'agent/lib/awcore/JIDAcore.jar').to exist + expect(sandbox + 'agent/lib/awcore/JidaSecurity.policy').to exist + expect(sandbox + 'agent/lib/awapp/JIDAapp.jar').to exist + expect(sandbox + 'agent/lib/awapp/JIDAutil.jar').to exist + expect(sandbox + 'agent/classes').to exist + end + end + end + + context do + + before do + allow(component).to receive(:architecture).and_return('x86_64') + end + context do + before do + allow(services).to receive(:find_service).and_return('credentials' => {}) + allow(component).to receive(:version).and_return('10.15.1_BL234') + end + it 'sets default values to java opts' do + component.release + expect(environment_variables).to include('DSA_PORT=2111') + expect(environment_variables).to include('RVBD_AGENT_PORT=7073') + expect(environment_variables).to include('AIX_INSTRUMENT_ALL=1') + expect(environment_variables).to include('RVBD_AGENT_FILES=1') + expect(environment_variables).to include('RVBD_JBP_VERSION=10.15.1_BL234') + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/' \ + 'riverbed_appinternals_agent/agent/lib/librpilj64.so') + end + end + + context do + before do + allow(services).to receive(:find_service).and_return('credentials' => { 'rvbd_dsa_port' => '10000', \ + 'rvbd_agent_port' => '20000', \ + 'rvbd_moniker' => 'special_name' }) + end + it 'sets customized values to java opts' do + component.release + expect(environment_variables).to include('DSA_PORT=10000') + expect(environment_variables).to include('RVBD_AGENT_PORT=20000') + expect(java_opts).to include('-Driverbed.moniker=special_name') + end + end + end +end From 0e30a6e883d35ca55e928c0508b0f8aa6220dd19 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 10 Jul 2018 14:32:29 -0700 Subject: [PATCH 430/812] Polishing [resolves #605] --- .idea/dictionaries/bhale.xml | 3 + docs/framework-riverbed_appinternals_agent.md | 2 +- .../framework/riverbed_appinternals_agent.rb | 108 +++++------------- .../riverbed_appinternals_agent_spec.rb | 98 ++++++---------- 4 files changed, 66 insertions(+), 145 deletions(-) diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index b23aaaaf0b..8c40705e96 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -4,6 +4,7 @@ addons agentpath appdynamics + appinternals applicationid argv aspectsecurity @@ -50,6 +51,7 @@ libcrpytoki libcryptoki libjvm + librpilj libruxitagentloader libyjpagent ljust @@ -88,6 +90,7 @@ rubo rubocop ruxit + rvbd safenet scriptdir sessionname diff --git a/docs/framework-riverbed_appinternals_agent.md b/docs/framework-riverbed_appinternals_agent.md index 6b551a04f9..606e1b37b3 100644 --- a/docs/framework-riverbed_appinternals_agent.md +++ b/docs/framework-riverbed_appinternals_agent.md @@ -3,7 +3,7 @@ The Riverbed Appinternals Agent Framework causes an application to be bound with - diff --git a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb index 06956c2368..988a1abd71 100644 --- a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb +++ b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb @@ -23,116 +23,66 @@ module Framework # Encapsulates the functionality for running the Riverbed Appinternals Agent support. class RiverbedAppinternalsAgent < JavaBuildpack::Component::VersionedDependencyComponent - # jbp constants - FILTER = /(?i)appinternals/ - - # credentials key - RVBD_DSA_PORT = 'rvbd_dsa_port' - RVBD_AGENT_PORT = 'rvbd_agent_port' - - # javaagent args - RVBD_MONIKER = 'rvbd_moniker' - - # env - AIX_INSTRUMENT_ALL = 'AIX_INSTRUMENT_ALL' - RVBD_AGENT_FILES = 'RVBD_AGENT_FILES' - DSA_PORT = 'DSA_PORT' - RVBD_JBP_VERSION = 'RVBD_JBP_VERSION' - - # constants - DSA_PORT_DEFAULT = 2111 - RVBD_AGENT_PORT_DEFAULT = 7073 - - private_constant :FILTER, :RVBD_AGENT_PORT, - :DSA_PORT, - :RVBD_MONIKER, - :AIX_INSTRUMENT_ALL, - :RVBD_AGENT_FILES, - :DSA_PORT_DEFAULT, - :RVBD_AGENT_PORT_DEFAULT, - :RVBD_DSA_PORT, - :RVBD_JBP_VERSION - - attr_reader :version - - def initialize(context) - super(context) - @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger RiverbedAppinternalsAgent - end # (see JavaBuildpack::Component::BaseComponent#compile) def compile download_zip(false, @droplet.sandbox, @component_name) - `echo "#{@version} is downloaded....\n" >> /#{@droplet.sandbox}/staging.log` @droplet.copy_resources end # (see JavaBuildpack::Component::BaseComponent#release) def release credentials = @application.services.find_service(FILTER)['credentials'] - setup_env credentials - setup_javaopts credentials - end - - def supports? - @application.services.one_service?(FILTER) && os.casecmp('Linux').zero? - end - private + @droplet.environment_variables + .add_environment_variable('AIX_INSTRUMENT_ALL', 1) + .add_environment_variable('DSA_PORT', dsa_port(credentials)) + .add_environment_variable('RVBD_AGENT_FILES', 1) + .add_environment_variable('RVBD_AGENT_PORT', agent_port(credentials)) + .add_environment_variable('RVBD_JBP_VERSION', @version) - def setup_javaopts(credentials) @droplet.java_opts.add_agentpath(agent_path) - rvbd_moniker = get_val_in_cred(RVBD_MONIKER, credentials[RVBD_MONIKER], nil, true) \ - || @configuration[RVBD_MONIKER] - @droplet.java_opts.add_system_property('riverbed.moniker', rvbd_moniker) unless rvbd_moniker.nil? - end - def get_val_in_cred(property, cred_val, default, logging) - @logger.debug { "picks up credential #{property}:#{cred_val}" } if cred_val && logging - cred_val ? cred_val : default + return unless rvbd_moniker(credentials) + @droplet.java_opts.add_system_property('riverbed.moniker', rvbd_moniker(credentials)) end - def setup_env(credentials) - @droplet.environment_variables - .add_environment_variable(DSA_PORT.upcase, get_val_in_cred(RVBD_DSA_PORT, \ - credentials[RVBD_DSA_PORT], \ - DSA_PORT_DEFAULT, true)) - .add_environment_variable(RVBD_AGENT_PORT.upcase, get_val_in_cred(RVBD_AGENT_PORT.upcase, \ - credentials[RVBD_AGENT_PORT], \ - RVBD_AGENT_PORT_DEFAULT, true)) - .add_environment_variable(AIX_INSTRUMENT_ALL, 1) - .add_environment_variable(RVBD_AGENT_FILES, 1) - .add_environment_variable(RVBD_JBP_VERSION, version) - end + protected - def architecture - `uname -m`.strip + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service?(FILTER) end - def os - `uname`.strip - end + private + + FILTER = /appinternals/ + + private_constant :FILTER def agent_path - lib_dir + lib_ripl_name + @droplet.sandbox + 'agent/lib' + lib_name end - def agent_dir - @droplet.sandbox + 'agent' + def agent_port(credentials) + credentials['rvbd_agent_port'] || 7073 end - def lib_dir - agent_dir + 'lib' + def architecture + `uname -m`.strip end - def classes_dir - agent_dir + 'classes' + def dsa_port(credentials) + credentials['rvbd_dsa_port'] || 2111 end - def lib_ripl_name - architecture == 'x86_64' || architecture == 'i686' ? 'librpilj64.so' : 'librpilj.so' + def lib_name + %w[x86_64 i686].include?(architecture) ? 'librpilj64.so' : 'librpilj.so' end + def rvbd_moniker(credentials) + credentials['rvbd_moniker'] || @configuration['rvbd_moniker'] + end end end end diff --git a/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb b/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb index 4b9e62a548..a03d1e05d1 100644 --- a/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb +++ b/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb @@ -22,85 +22,53 @@ describe JavaBuildpack::Framework::RiverbedAppinternalsAgent do include_context 'with component help' - context do - it 'does not support riverbed-appinternals-agent service' do - expect(component.supports?).to be false - end - - it 'cannot detect riverbed-appinternals-agent service' do - expect(component.detect).to eq(nil) - end + it 'does detect riverbed-appinternals-agent service' do + expect(component.detect).to be_nil end context do - let(:vcap_services) do - - { 'test-service-n/a' => [{ 'name' => 'appinternals_test_service', 'label' => 'test-service-n/a',\ - 'tags' => ['test-service-tag'], 'plan' => 'test-plan',\ - 'credentials' => { 'uri' => 'test-uri' } }] } - end - - it 'supports riverbed-appinternals-agent service' do - expect(component.supports?).to be true + before do + allow(services).to receive(:one_service?).with(/appinternals/).and_return(true) end it 'detects with riverbed-appinternals-agent service' do expect(component.detect).to eq("riverbed-appinternals-agent=#{version}") end - context do - it 'unzip riverbed appinternals agent zip file', - cache_fixture: 'stub-riverbed-appinternals-agent.zip' do - - component.compile - - expect(sandbox + 'agent/lib/libAwProfile64.so').to exist - expect(sandbox + 'agent/lib/libAwProfile.so').to exist - expect(sandbox + 'agent/lib/librpilj.so').to exist - expect(sandbox + 'agent/lib/librpilj64.so').to exist - expect(sandbox + 'agent/lib/awcore/JIDAcore.jar').to exist - expect(sandbox + 'agent/lib/awcore/JidaSecurity.policy').to exist - expect(sandbox + 'agent/lib/awapp/JIDAapp.jar').to exist - expect(sandbox + 'agent/lib/awapp/JIDAutil.jar').to exist - expect(sandbox + 'agent/classes').to exist - end - end - end - context do + it 'unzips riverbed appinternals agent zip file', + cache_fixture: 'stub-riverbed-appinternals-agent.zip' do - before do - allow(component).to receive(:architecture).and_return('x86_64') + component.compile + + expect(sandbox + 'agent/lib/librpilj64.so').to exist end - context do - before do - allow(services).to receive(:find_service).and_return('credentials' => {}) - allow(component).to receive(:version).and_return('10.15.1_BL234') - end - it 'sets default values to java opts' do - component.release - expect(environment_variables).to include('DSA_PORT=2111') - expect(environment_variables).to include('RVBD_AGENT_PORT=7073') - expect(environment_variables).to include('AIX_INSTRUMENT_ALL=1') - expect(environment_variables).to include('RVBD_AGENT_FILES=1') - expect(environment_variables).to include('RVBD_JBP_VERSION=10.15.1_BL234') - expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/' \ - 'riverbed_appinternals_agent/agent/lib/librpilj64.so') - end + + it 'updates JAVA_OPTS' do + allow(services).to receive(:find_service).and_return('credentials' => {}) + + component.release + + expect(environment_variables).to include('AIX_INSTRUMENT_ALL=1') + expect(environment_variables).to include('DSA_PORT=2111') + expect(environment_variables).to include('RVBD_AGENT_FILES=1') + expect(environment_variables).to include('RVBD_AGENT_PORT=7073') + expect(environment_variables).to include('RVBD_JBP_VERSION=0.0.0') + + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/riverbed_appinternals_agent/agent/lib/' \ + 'librpilj64.so') end - context do - before do - allow(services).to receive(:find_service).and_return('credentials' => { 'rvbd_dsa_port' => '10000', \ - 'rvbd_agent_port' => '20000', \ - 'rvbd_moniker' => 'special_name' }) - end - it 'sets customized values to java opts' do - component.release - expect(environment_variables).to include('DSA_PORT=10000') - expect(environment_variables).to include('RVBD_AGENT_PORT=20000') - expect(java_opts).to include('-Driverbed.moniker=special_name') - end + it 'updates JAVA_OPTS with credentials' do + allow(services).to receive(:find_service).and_return('credentials' => { 'rvbd_dsa_port' => '10000', \ + 'rvbd_agent_port' => '20000', \ + 'rvbd_moniker' => 'special_name' }) + + component.release + + expect(environment_variables).to include('DSA_PORT=10000') + expect(environment_variables).to include('RVBD_AGENT_PORT=20000') + expect(java_opts).to include('-Driverbed.moniker=special_name') end end end From 96e26dd81ebf4b90616a747e6527aaf60dde4099 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 10 Jul 2018 14:32:48 -0700 Subject: [PATCH 431/812] IDEA Artifact --- .idea/google-java-format.xml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .idea/google-java-format.xml diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml new file mode 100644 index 0000000000..2aa056da34 --- /dev/null +++ b/.idea/google-java-format.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file From 15aba02c93f9bdb87d7a27af2ad7c685ac2015ef Mon Sep 17 00:00:00 2001 From: fwanggg Date: Wed, 11 Jul 2018 10:59:42 -0400 Subject: [PATCH 432/812] Add Riverbed to README A previous contribution to the buildpack added Riverbed Appinternals support but did not add the documentation to the main README. This change adds a link to the README for the framework's documentation. [resolves #607] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 738a27ece3..ce33d4fc00 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ The buildpack supports extension through the use of Git repository forking. The * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) + * [Riverbed AppInternals Agent](docs/framework-riverbed_appinternals_agent.md) ([Configuration](docs/framework-riverbed_appinternals_agent.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) * [Spring Insight](docs/framework-spring_insight.md) * [SkyWalking Agent](docs/framework-sky_walking_agent.md) ([Configuration](docs/framework-sky_walking_agent.md#configuration)) From 189bcd7c08728682f833df10c1eb0d00c22482c6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 11 Jul 2018 09:44:09 -0700 Subject: [PATCH 433/812] Polishing --- config/app_dynamics_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index b4567afd22..79836f988f 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -19,4 +19,4 @@ version: 4.+ repository_root: https://packages.appdynamics.com/java default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name") default_node_name: $(jq -r -n "$VCAP_APPLICATION | .application_name + \":$CF_INSTANCE_INDEX\"") -default_tier_name: +default_tier_name: From 0ef9a591f96bd39c88db3011af455ebec08dac68 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 27 Mar 2018 14:04:31 -0700 Subject: [PATCH 434/812] Google Stackdriver Profiler This change adds support for the Google Stackdriver Profiler. --- .idea/dictionaries/bhale.xml | 3 + README.md | 1 + config/components.yml | 1 + config/google_stackdriver_profiler.yml | 21 ++++ docs/framework-google_stackdriver_profiler.md | 43 ++++++++ docs/jre-zulu_jre.md | 0 .../framework/google_stackdriver_profiler.rb | 101 ++++++++++++++++++ rakelib/versions_task.rb | 1 + .../stub-google-stackdriver-profiler.tar.gz | Bin 0 -> 167 bytes .../google_stackdriver_profiler_spec.rb | 76 +++++++++++++ 10 files changed, 247 insertions(+) create mode 100644 config/google_stackdriver_profiler.yml create mode 100644 docs/framework-google_stackdriver_profiler.md mode change 100755 => 100644 docs/jre-zulu_jre.md create mode 100644 lib/java_buildpack/framework/google_stackdriver_profiler.rb create mode 100644 spec/fixtures/stub-google-stackdriver-profiler.tar.gz create mode 100644 spec/java_buildpack/framework/google_stackdriver_profiler_spec.rb diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 8c40705e96..db86f3320e 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -18,6 +18,7 @@ constantized constantizes cpio + cprof creat cryptoki dhttp @@ -55,6 +56,7 @@ libruxitagentloader libyjpagent ljust + logtostderr lunaclient lunajsp mainclass @@ -97,6 +99,7 @@ shellwords simplecov socketfactory + stackdriver stderr strftime stringifies diff --git a/README.md b/README.md index ce33d4fc00..6298a7b621 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ The buildpack supports extension through the use of Git repository forking. The * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) * [Google Stackdriver Debugger](docs/framework-google_stackdriver_debugger.md) ([Configuration](docs/framework-google_stackdriver_debugger.md#configuration)) + * [Google Stackdriver Profiler](docs/framework-google_stackdriver_profiler.md) ([Configuration](docs/framework-google_stackdriver_profiler.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [JaCoCo Agent](docs/framework-jacoco_agent.md) ([Configuration](docs/framework-jacoco_agent.md#configuration)) * [Java Memory Assistant](docs/framework-java_memory_assistant.md) ([Configuration](docs/framework-java_memory_assistant.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 546f80aa48..e21195e799 100644 --- a/config/components.yml +++ b/config/components.yml @@ -51,6 +51,7 @@ frameworks: - "JavaBuildpack::Framework::DynatraceAppmonAgent" - "JavaBuildpack::Framework::DynatraceOneAgent" - "JavaBuildpack::Framework::GoogleStackdriverDebugger" + - "JavaBuildpack::Framework::GoogleStackdriverProfiler" - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::JacocoAgent" - "JavaBuildpack::Framework::JavaMemoryAssistant" diff --git a/config/google_stackdriver_profiler.yml b/config/google_stackdriver_profiler.yml new file mode 100644 index 0000000000..6a65f9dfb4 --- /dev/null +++ b/config/google_stackdriver_profiler.yml @@ -0,0 +1,21 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Groovy container +--- +version: 0.+ +repository_root: "{default.repository.root}/google-stackdriver-profiler/{platform}/{architecture}" +application_name: +application_version: diff --git a/docs/framework-google_stackdriver_profiler.md b/docs/framework-google_stackdriver_profiler.md new file mode 100644 index 0000000000..4781be1d1a --- /dev/null +++ b/docs/framework-google_stackdriver_profiler.md @@ -0,0 +1,43 @@ +# Google Stackdriver Profielr Framework +The Google Stackdriver Profiler Framework causes an application to be automatically configured to work with a bound [Google Stackdriver Profiler Service][]. + +
Detection CriterionExistence of a single bound Riverbed Appinternals agent service. The existence of an agent service is defined by the VCAP_SERVICES payload containing a service name, label or tag with appinternals as a substring (the substring is case insensitive). + Detection CriterionExistence of a single bound Riverbed Appinternals agent service. The existence of an agent service is defined by the VCAP_SERVICES payload containing a service name, label or tag with appinternals as a substring.
+ + + + + + + +
Detection CriterionExistence of a single bound Google Stackdriver Profiler service. +
    +
  • Existence of a Google Stackdriver Profiler service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has google-stackdriver-profiler as a substring.
  • +
+
Tagsgoogle-stackdriver-profiler=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service (Optional) +Users may optionally provide their own Google Stackdriver Profiler service. A user-provided Google Stackdriver Profiler service must have a name or tag with `google-stackdriver-profiler` in it so that the Google Stackdriver Profiler Agent Framework will automatically configure the application to work with the service. + +The credential payload of the service must contain the following entry: + +| Name | Description +| ---- | ----------- +| `PrivateKeyData` | A Base64 encoded Service Account JSON payload + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/google_stackdriver_profiler.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Google Stackdriver Profiler repository index ([details][repositories]). +| `version` | The version of Google Stackdriver Profiler to use. Candidate versions can be found in [this listing][]. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[`config/google_stackdriver_profiler.yml`]: ../config/google_stackdriver_profiler.yml +[Google Stackdriver Profiler Service]: https://cloud.google.com/profiler/ +[repositories]: extending-repositories.md +[this listing]: http://download.pivotal.io.s3.amazonaws.com/google-stackdriver-profiler/trusty/x86_64/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md old mode 100755 new mode 100644 diff --git a/lib/java_buildpack/framework/google_stackdriver_profiler.rb b/lib/java_buildpack/framework/google_stackdriver_profiler.rb new file mode 100644 index 0000000000..856cd38225 --- /dev/null +++ b/lib/java_buildpack/framework/google_stackdriver_profiler.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'base64' +require 'json' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Google Cloud Profiler support. + class GoogleStackdriverProfiler < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_tar false + + write_json_file private_key_data + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + java_opts = @droplet.java_opts + + java_opts + .add_agentpath_with_props(@droplet.sandbox + 'profiler_java_agent.so', + '--logtostderr' => 1, + '-cprof_project_id' => project_id, + '-cprof_service' => application_name, + '-cprof_service_version' => application_version) + + @droplet.environment_variables.add_environment_variable 'GOOGLE_APPLICATION_CREDENTIALS', json_file + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, PRIVATE_KEY_DATA + end + + FILTER = /google-stackdriver-profiler/ + + PRIVATE_KEY_DATA = 'PrivateKeyData' + + private_constant :FILTER, :PRIVATE_KEY_DATA + + private + + def application_name + @configuration['application_name'] || @application.details['application_name'] + end + + def application_version + @configuration['application_version'] || @application.details['application_version'] + end + + def credentials + @application.services.find_service(FILTER, PRIVATE_KEY_DATA)['credentials'] + end + + def private_key_data + Base64.decode64 credentials[PRIVATE_KEY_DATA] + end + + def project_id + JSON.parse(private_key_data)['project_id'] + end + + def json_file + @droplet.sandbox + 'svc.json' + end + + def write_json_file(private_key_data) + FileUtils.mkdir_p json_file.parent + json_file.open(File::CREAT | File::WRONLY) do |f| + f.write "#{private_key_data}\n" + f.sync + f + end + end + + end + + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 0c75e6d1e0..dd7d75bf11 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -64,6 +64,7 @@ def initialize 'dynatrace_one_agent' => 'Dynatrace OneAgent', 'geode_store' => 'Geode Tomcat Session Store', 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', + 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', 'groovy' => 'Groovy', 'introscope_agent' => 'CA Introscope APM Framework', 'jacoco_agent' => 'JaCoCo Agent', diff --git a/spec/fixtures/stub-google-stackdriver-profiler.tar.gz b/spec/fixtures/stub-google-stackdriver-profiler.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..6f4deae0b1bbe918802a215014604dae2ba2037e GIT binary patch literal 167 zcmb2|=3qFqepeI&^V^H}xtbM3ju*-wRW~r*dYqGeoBa`~tKa@i?z*chamDq`@0~vz zoIge)B-?wK# S0u7I=m=`!7{>-4kzyJWH2v5`i literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/google_stackdriver_profiler_spec.rb b/spec/java_buildpack/framework/google_stackdriver_profiler_spec.rb new file mode 100644 index 0000000000..56218e5b40 --- /dev/null +++ b/spec/java_buildpack/framework/google_stackdriver_profiler_spec.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/google_stackdriver_profiler' + +describe JavaBuildpack::Framework::GoogleStackdriverProfiler do + include_context 'with component help' + + it 'does not detect without google-stackdriver-profiler service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?) + .with(/google-stackdriver-profiler/, 'PrivateKeyData').and_return(true) + + allow(services).to receive(:find_service).and_return( + 'credentials' => { + 'PrivateKeyData' => 'eyJwcm9qZWN0X2lkIjoidGVzdC1wcm9qZWN0LWlkIn0=' + } + ) + end + + it 'detects with google-stackdriver-profiler service' do + expect(component.detect).to eq("google-stackdriver-profiler=#{version}") + end + + it 'unpacks the google stackdriver debugger tar', + cache_fixture: 'stub-google-stackdriver-profiler.tar.gz' do + + component.compile + + expect(sandbox + 'profiler_java_agent.so').to exist + end + + it 'writes JSON file', + cache_fixture: 'stub-google-stackdriver-profiler.tar.gz' do + + component.compile + + expect(sandbox + 'svc.json').to exist + expect(File.read(sandbox + 'svc.json')).to eq("{\"project_id\":\"test-project-id\"}\n") + end + + it 'updates JAVA_OPTS' do + component.release + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/google_stackdriver_profiler/' \ + 'profiler_java_agent.so=--logtostderr=1,-cprof_project_id=test-project-id,' \ + '-cprof_service=test-application-name,' \ + '-cprof_service_version=test-application-version') + + expect(environment_variables).to include('GOOGLE_APPLICATION_CREDENTIALS=' \ + '$PWD/.java-buildpack/google_stackdriver_profiler/svc.json') + end + + end + +end From d8f60627396a5e7422ee6bc1ee69b6f67f84225e Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 26 Jul 2018 13:06:16 -0700 Subject: [PATCH 435/812] Update Spring Boot CLI to 2.x This change updates the Spring Boot CLI to the 2.x line. [resolves #611] --- config/spring_boot_cli.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/spring_boot_cli.yml b/config/spring_boot_cli.yml index bb833d222e..6af6b2ac78 100644 --- a/config/spring_boot_cli.yml +++ b/config/spring_boot_cli.yml @@ -17,5 +17,5 @@ # Note that the repository is shared with the Play Auto Reconfiguration framework and should be kept in step to # avoid conflicts. --- -version: 1.+ +version: 2.+ repository_root: "{default.repository.root}/spring-boot-cli" From 0c42999493104f720741b12172981679eebd8868 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 26 Jul 2018 13:29:11 -0700 Subject: [PATCH 436/812] Distribute Bionic Binaries This change updates the offline packaging build to include both bionic and trusty binaries. [resolves #610] --- rakelib/package.rb | 2 +- rakelib/versions_task.rb | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rakelib/package.rb b/rakelib/package.rb index a423f64236..6a80200cee 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -33,7 +33,7 @@ def self.version BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze - PLATFORMS = %w[trusty].freeze + PLATFORMS = %w[bionic trusty].freeze STAGING_DIR = "#{BUILD_DIR}/staging" diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index dd7d75bf11..e19e1068cd 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -202,7 +202,9 @@ def dependency_versions end end - dependency_versions.sort_by { |dependency| dependency['id'] } + dependency_versions + .uniq { |dependency| dependency['id']} + .sort_by { |dependency| dependency['id'] } end def index_configuration(configuration) From 14734bd954709786212c6b4dc6ef499d43cb9220 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 26 Jul 2018 15:05:14 -0700 Subject: [PATCH 437/812] Polishing --- rakelib/versions_task.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index e19e1068cd..4c1d6815c9 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -203,7 +203,7 @@ def dependency_versions end dependency_versions - .uniq { |dependency| dependency['id']} + .uniq { |dependency| dependency['id'] } .sort_by { |dependency| dependency['id'] } end From 84b4e6898a7c96813660bb70dfc0c5aee1d3374c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 26 Jul 2018 16:49:10 -0700 Subject: [PATCH 438/812] Revert "Update Spring Boot CLI to 2.x" This reverts commit d8f60627396a5e7422ee6bc1ee69b6f67f84225e. --- config/spring_boot_cli.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/spring_boot_cli.yml b/config/spring_boot_cli.yml index 6af6b2ac78..bb833d222e 100644 --- a/config/spring_boot_cli.yml +++ b/config/spring_boot_cli.yml @@ -17,5 +17,5 @@ # Note that the repository is shared with the Play Auto Reconfiguration framework and should be kept in step to # avoid conflicts. --- -version: 2.+ +version: 1.+ repository_root: "{default.repository.root}/spring-boot-cli" From e863d2a9c14a65ea1e466669f80ecb55d728a88f Mon Sep 17 00:00:00 2001 From: Ryan Morgan Date: Mon, 30 Jul 2018 15:21:43 -0500 Subject: [PATCH 439/812] Fix Typo for Stackdriver Profiler [resolves #613] --- docs/framework-google_stackdriver_profiler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-google_stackdriver_profiler.md b/docs/framework-google_stackdriver_profiler.md index 4781be1d1a..d290f3b491 100644 --- a/docs/framework-google_stackdriver_profiler.md +++ b/docs/framework-google_stackdriver_profiler.md @@ -1,4 +1,4 @@ -# Google Stackdriver Profielr Framework +# Google Stackdriver Profiler Framework The Google Stackdriver Profiler Framework causes an application to be automatically configured to work with a bound [Google Stackdriver Profiler Service][]. From 8e5113dc06c134e0bb8a38235cd1f136caa9a3fb Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 1 Aug 2018 09:39:37 -0500 Subject: [PATCH 440/812] New Relic 4.x This change updates the New Relic framework to use the new 4.x line. [resolves #614] --- config/new_relic_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/new_relic_agent.yml b/config/new_relic_agent.yml index 799747a926..f4c328a4cd 100644 --- a/config/new_relic_agent.yml +++ b/config/new_relic_agent.yml @@ -15,5 +15,5 @@ # Configuration for the New Relic framework --- -version: 3.+ +version: 4.+ repository_root: https://download.run.pivotal.io/new-relic From 0d376f2718b2cc86af0fd6b70cb9c3c76608070c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 6 Aug 2018 15:01:35 -0700 Subject: [PATCH 441/812] JProfiler Integration This change adds JProfiler Integration to the buildpack. [resolves #617] --- .idea/.rakeTasks | 2 +- .idea/dictionaries/bhale.xml | 1 + README.md | 1 + config/components.yml | 1 + config/jprofiler_profiler.yml | 22 +++++ docs/framework-jprofiler_profiler.md | 46 ++++++++++ docs/framework-jprofiler_profiler.png | Bin 0 -> 76532 bytes docs/framework-your_kit_profiler.md | 2 +- lib/java_buildpack/component/java_opts.rb | 2 +- .../framework/jprofiler_profiler.rb | 75 +++++++++++++++++ rakelib/versions_task.rb | 75 +++++++++-------- spec/fixtures/stub-jprofiler-profiler.tar.gz | Bin 0 -> 211 bytes .../framework/jprofiler_profiler_spec.rb | 79 ++++++++++++++++++ 13 files changed, 266 insertions(+), 40 deletions(-) create mode 100644 config/jprofiler_profiler.yml create mode 100644 docs/framework-jprofiler_profiler.md create mode 100644 docs/framework-jprofiler_profiler.png create mode 100644 lib/java_buildpack/framework/jprofiler_profiler.rb create mode 100644 spec/fixtures/stub-jprofiler-profiler.tar.gz create mode 100644 spec/java_buildpack/framework/jprofiler_profiler_spec.rb diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index d3feb8c181..22d96e4075 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index db86f3320e..9d1633adc0 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -51,6 +51,7 @@ libcklog libcrpytoki libcryptoki + libjprofilerti libjvm librpilj libruxitagentloader diff --git a/README.md b/README.md index 6298a7b621..dff13a9dac 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ The buildpack supports extension through the use of Git repository forking. The * [JaCoCo Agent](docs/framework-jacoco_agent.md) ([Configuration](docs/framework-jacoco_agent.md#configuration)) * [Java Memory Assistant](docs/framework-java_memory_assistant.md) ([Configuration](docs/framework-java_memory_assistant.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) + * [JProfiler Profiler](docs/framework-jprofiler_profiler.md) ([Configuration](docs/framework-jprofiler_profiler.md#configuration)) * [JRebel Agent](docs/framework-jrebel_agent.md) ([Configuration](docs/framework-jrebel_agent.md#configuration)) * [JMX](docs/framework-jmx.md) ([Configuration](docs/framework-jmx.md#configuration)) * [Luna Security Provider](docs/framework-luna_security_provider.md) ([Configuration](docs/framework-luna_security_provider.md#configuration)) diff --git a/config/components.yml b/config/components.yml index e21195e799..fea4f5b43e 100644 --- a/config/components.yml +++ b/config/components.yml @@ -56,6 +56,7 @@ frameworks: - "JavaBuildpack::Framework::JacocoAgent" - "JavaBuildpack::Framework::JavaMemoryAssistant" - "JavaBuildpack::Framework::Jmx" + - "JavaBuildpack::Framework::JprofilerProfiler" - "JavaBuildpack::Framework::JrebelAgent" - "JavaBuildpack::Framework::LunaSecurityProvider" - "JavaBuildpack::Framework::MariaDbJDBC" diff --git a/config/jprofiler_profiler.yml b/config/jprofiler_profiler.yml new file mode 100644 index 0000000000..b851f5e804 --- /dev/null +++ b/config/jprofiler_profiler.yml @@ -0,0 +1,22 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# JMX configuration +--- +version: 10.+ +repository_root: https://download.run.pivotal.io/jprofiler +enabled: false +nowait: true +port: 8849 diff --git a/docs/framework-jprofiler_profiler.md b/docs/framework-jprofiler_profiler.md new file mode 100644 index 0000000000..42902ac42f --- /dev/null +++ b/docs/framework-jprofiler_profiler.md @@ -0,0 +1,46 @@ +# JProfiler Profiler Framework +The JProfiler Profiler Framework contributes JProfiler configuration to the application at runtime. + +
+ + + + + + + + +
Detection Criterionenabled set in the config/jprofiler_profiler.yml file
Tagsjprofiler-profiler=<version>
+Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by creating or modifying the [`config/jprofiler_profiler.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `enabled` | Whether to enable the JProfiler Profiler +| `port` | The port that the JProfiler Profiler will listen on. Defaults to `8849`. +| `nowait` | Whether to start process without waiting for JProfiler to connect first. Defaults to `true`. +| `repository_root` | The URL of the JProfiler Profiler repository index ([details][repositories]). +| `version` | The version of the JProfiler Profiler to use. Candidate versions can be found in [this listing][]. + +## Creating SSH Tunnel +After starting an application with the JPorfiler Profiler enabled, an SSH tunnel must be created to the container. To create that SSH container, execute the following command: + +```bash +$ cf ssh -N -T -L :localhost: +``` + +The `REMOTE_PORT` should match the `port` configuration for the application (`8849` by default). The `LOCAL_PORT` can be any open port on your computer, but typically matches the `REMOTE_PORT` where possible. + +Once the SSH tunnel has been created, your JProfiler Profiler should connect to `localhost:` for debugging. + +![JProfiler Configuration](framework-jprofiler_profiler.png) + +[`config/jprofiler_profiler.yml`]: ../config/jprofiler_profiler.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[this listing]: http://download.pivotal.io.s3.amazonaws.com/jprofiler/index.yml +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/framework-jprofiler_profiler.png b/docs/framework-jprofiler_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..e7d34c898b0068c0e1ffc61479e0b56b084c3604 GIT binary patch literal 76532 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⋙|VGY*!ok5k8K!)p*ypD9{g}n(<$m%l7mt% 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 L-qq~OcOL&g<9GbM literal 0 HcmV?d00001 diff --git a/docs/framework-your_kit_profiler.md b/docs/framework-your_kit_profiler.md index ab478f2bf6..5792b51915 100644 --- a/docs/framework-your_kit_profiler.md +++ b/docs/framework-your_kit_profiler.md @@ -1,5 +1,5 @@ # YourKit Profiler Framework -The YourKit Profiler Framework contributes YourKit Profielr configuration to the application at runtime. **Note:** This framework is only useful in Diego-based containers with SSH access enabled. +The YourKit Profiler Framework contributes YourKit Profiler configuration to the application at runtime. diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index 8dc9b11181..40ad1ee222 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -60,7 +60,7 @@ def add_javaagent_with_props(path, props) # @param [Properties] props to append to the +agentpath+ entry # @return [JavaOpts] +self+ for chaining def add_agentpath_with_props(path, props) - add_preformatted_options "-agentpath:#{qualify_path path}=" + props.map { |k, v| "#{k}=#{v}" }.join(',') + add_preformatted_options "-agentpath:#{qualify_path path}=" + props.map { |k, v| v ? "#{k}=#{v}" : k }.join(',') end # Adds an +agentpath+ entry to the +JAVA_OPTS+. Prepends +$PWD+ to the path (relative to the droplet root) to diff --git a/lib/java_buildpack/framework/jprofiler_profiler.rb b/lib/java_buildpack/framework/jprofiler_profiler.rb new file mode 100644 index 0000000000..7a2ef50f1b --- /dev/null +++ b/lib/java_buildpack/framework/jprofiler_profiler.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/qualify_path' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch JProfiler profiler support. + class JprofilerProfiler < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + def initialize(context, &version_validator) + super(context, &version_validator) + @component_name = 'JProfiler Profiler' + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_tar + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + properties = { 'port' => port } + properties['nowait'] = nil if nowait + + @droplet + .java_opts + .add_agentpath_with_props(file_name, properties) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @configuration['enabled'] + end + + private + + def file_name + @droplet.sandbox + 'bin/linux-x64/libjprofilerti.so' + end + + def nowait + v = @configuration['nowait'] + v.nil? ? true : v + end + + def port + @configuration['port'] || 8_849 + end + + end + + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 4c1d6815c9..15d4a0190f 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -51,43 +51,44 @@ def initialize DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/ NAME_MAPPINGS = { - 'access_logging_support' => 'Tomcat Access Logging Support', - 'agent' => 'Java Memory Assistant Agent', - 'app_dynamics_agent' => 'AppDynamics Agent', - 'clean_up' => 'Java Memory Assistant Clean Up', - 'client_certificate_mapper' => 'Client Certificate Mapper', - 'container_customizer' => 'Spring Boot Container Customizer', - 'container_security_provider' => 'Container Security Provider', - 'contrast_security_agent' => 'Contrast Security Agent', - 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', - 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', - 'dynatrace_one_agent' => 'Dynatrace OneAgent', - 'geode_store' => 'Geode Tomcat Session Store', - 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', - 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', - 'groovy' => 'Groovy', - 'introscope_agent' => 'CA Introscope APM Framework', - 'jacoco_agent' => 'JaCoCo Agent', - 'jre' => 'OpenJDK JRE', - 'jrebel_agent' => 'JRebel Agent', - 'jvmkill_agent' => 'jvmkill Agent', - 'lifecycle_support' => 'Tomcat Lifecycle Support', - 'logging_support' => 'Tomcat Logging Support', - 'luna_security_provider' => 'Gemalto Luna Security Provider', - 'maria_db_jdbc' => 'MariaDB JDBC Driver', - 'memory_calculator' => 'Memory Calculator', - 'metric_writer' => 'Metric Writer', - 'new_relic_agent' => 'New Relic Agent', - 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', - 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', - 'redis_store' => 'Redis Session Store', - 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', - 'sky_walking_agent' => 'SkyWalking', - 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', - 'spring_boot_cli' => 'Spring Boot CLI', - 'takipi_agent' => 'Takipi Agent', - 'tomcat' => 'Tomcat', - 'your_kit_profiler' => 'YourKit Profiler' + 'access_logging_support' => 'Tomcat Access Logging Support', + 'agent' => 'Java Memory Assistant Agent', + 'app_dynamics_agent' => 'AppDynamics Agent', + 'clean_up' => 'Java Memory Assistant Clean Up', + 'client_certificate_mapper' => 'Client Certificate Mapper', + 'container_customizer' => 'Spring Boot Container Customizer', + 'container_security_provider' => 'Container Security Provider', + 'contrast_security_agent' => 'Contrast Security Agent', + 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', + 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', + 'dynatrace_one_agent' => 'Dynatrace OneAgent', + 'geode_store' => 'Geode Tomcat Session Store', + 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', + 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', + 'groovy' => 'Groovy', + 'introscope_agent' => 'CA Introscope APM Framework', + 'jacoco_agent' => 'JaCoCo Agent', + 'jprofiler_profiler' => 'JProfiler Profiler', + 'jre' => 'OpenJDK JRE', + 'jrebel_agent' => 'JRebel Agent', + 'jvmkill_agent' => 'jvmkill Agent', + 'lifecycle_support' => 'Tomcat Lifecycle Support', + 'logging_support' => 'Tomcat Logging Support', + 'luna_security_provider' => 'Gemalto Luna Security Provider', + 'maria_db_jdbc' => 'MariaDB JDBC Driver', + 'memory_calculator' => 'Memory Calculator', + 'metric_writer' => 'Metric Writer', + 'new_relic_agent' => 'New Relic Agent', + 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', + 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', + 'redis_store' => 'Redis Session Store', + 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', + 'sky_walking_agent' => 'SkyWalking', + 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', + 'spring_boot_cli' => 'Spring Boot CLI', + 'takipi_agent' => 'Takipi Agent', + 'tomcat' => 'Tomcat', + 'your_kit_profiler' => 'YourKit Profiler' }.freeze PLATFORM_PATTERN = /\{platform\}/ diff --git a/spec/fixtures/stub-jprofiler-profiler.tar.gz b/spec/fixtures/stub-jprofiler-profiler.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..535bd3505eb6c59d1db249a7ef999aeba72ee140 GIT binary patch literal 211 zcmV;^04)C>iwFQE%V=8w1MSn@3W6{g#&IuYH;}#i^m-DM7NVgAU4EmYg9yP;LHhqr zo`b!x&1as@eOJe(>b2xLH~VY>B2sv-9vPk~#y#^zX=|;~&ReIIXj_;fQ+|oVe7X*o zL!XXP9uG}5GMC2cdSv}|k9Tgw>7)NLwzI#1DgB!?C@IC#{~Esa-^BKM+ueej=_O3+ zKbX{iFrNQ^732Lkv3w6)Vm@>~?UBAmaBf2XMh7dIl9})N)t~nd00000000000002C N?+zi`bEp6)007-^WfA}Y literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/jprofiler_profiler_spec.rb b/spec/java_buildpack/framework/jprofiler_profiler_spec.rb new file mode 100644 index 0000000000..0248a5e596 --- /dev/null +++ b/spec/java_buildpack/framework/jprofiler_profiler_spec.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/jprofiler_profiler' + +describe JavaBuildpack::Framework::JprofilerProfiler do + include_context 'with component help' + + it 'does not detect if not enabled' do + expect(component.detect).to be_nil + end + + context do + let(:configuration) { { 'enabled' => true } } + + it 'detects when enabled' do + expect(component.detect).to eq("jprofiler-profiler=#{version}") + end + + it 'downloads YourKit agent', + cache_fixture: 'stub-jprofiler-profiler.tar.gz' do + + component.compile + + expect(sandbox + 'bin/linux-x64/libjprofilerti.so').to exist + end + + context do + it 'updates JAVA_OPTS' do + component.release + + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jprofiler_profiler/bin/linux-x64/' \ + 'libjprofilerti.so=port=8849,nowait') + + end + + context do + let(:configuration) { super().merge 'port' => 8_850 } + + it 'adds port from configuration to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jprofiler_profiler/bin/linux-x64/' \ + 'libjprofilerti.so=port=8850,nowait') + end + end + + context do + let(:configuration) { super().merge 'nowait' => false } + + it 'disables nowait in JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jprofiler_profiler/bin/linux-x64/' \ + 'libjprofilerti.so=port=8849') + end + end + + end + + end + +end From 30f58f7d38d8dad41d823ee059f053eb976269e2 Mon Sep 17 00:00:00 2001 From: Dmitri Gabbasov Date: Fri, 24 Aug 2018 18:01:41 +0300 Subject: [PATCH 442/812] Update JRebel version JRebel now follows a versioning scheme where the "major" version is the year when that version was released. As such, it doesn't make sense to fix a specific major version anymore. [resolves #623] --- config/jrebel_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml index 732b3d1e7a..25db540f5c 100644 --- a/config/jrebel_agent.yml +++ b/config/jrebel_agent.yml @@ -15,6 +15,6 @@ # Configuration for the JRebel framework --- -version: 7.+ +version: + repository_root: https://dl.zeroturnaround.com/jrebel enabled: true From 56350c2f0fc431967821a5c170b9c62caf8854a9 Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Thu, 13 Sep 2018 11:29:45 +0200 Subject: [PATCH 443/812] updated appmon version and download url --- config/dynatrace_appmon_agent.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/dynatrace_appmon_agent.yml b/config/dynatrace_appmon_agent.yml index 1b2d780ba1..3f8732da86 100644 --- a/config/dynatrace_appmon_agent.yml +++ b/config/dynatrace_appmon_agent.yml @@ -15,6 +15,6 @@ # Configuration for the Dynatrace framework --- -version: 6.3.0_+ -repository_root: http://downloads.dynatracesaas.com/cloudfoundry/buildpack/java -default_agent_name: +version: 7.1.0_+ +repository_root: http://files.dynatrace.com/downloads/appmon/cloudfoundry/buildpack/java +default_agent_name: From fa069c4952b55aa003f0d93aeddcb14efbd885ad Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Thu, 13 Sep 2018 12:53:52 +0200 Subject: [PATCH 444/812] Appmon Version and URL This change updates the version wildcard and download URI for the Dynatrace Appmon agent. [resolves #632] --- config/dynatrace_appmon_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/dynatrace_appmon_agent.yml b/config/dynatrace_appmon_agent.yml index 3f8732da86..5012feb6c6 100644 --- a/config/dynatrace_appmon_agent.yml +++ b/config/dynatrace_appmon_agent.yml @@ -16,5 +16,5 @@ # Configuration for the Dynatrace framework --- version: 7.1.0_+ -repository_root: http://files.dynatrace.com/downloads/appmon/cloudfoundry/buildpack/java +repository_root: https://files.dynatrace.com/downloads/appmon/cloudfoundry/buildpack/java default_agent_name: From 6333bb7e28fd7b90dab4e7b228979093e6f8d3b3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 18 Sep 2018 10:53:50 -0700 Subject: [PATCH 445/812] Documentation Updated Previously the link to running CF locally using BOSH Lite was broken. This change updates that link to the new documentation on how to run CF locally. [resolves #629] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dff13a9dac..b52f90f76e 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,6 @@ This buildpack is released under version 2.0 of the [Apache License][]. [Play Framework]: http://www.playframework.com [pull request]: https://help.github.com/articles/using-pull-requests [Pull requests]: http://help.github.com/send-pull-requests -[Running Cloud Foundry locally]: http://docs.cloudfoundry.org/deploying/boshlite/index.html +[Running Cloud Foundry locally]: https://github.com/cloudfoundry/cf-deployment/tree/master/iaas-support/bosh-lite [Spring Boot]: http://projects.spring.io/spring-boot/ [Wikipedia]: https://en.wikipedia.org/wiki/YAML#Basic_components_of_YAML From 3c22bb4a2cf81b814eb4bbe944b319b5ef53a98e Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 18 Sep 2018 14:45:41 -0700 Subject: [PATCH 446/812] Dependency Updates --- .rubocop.yml | 16 ++- Gemfile | 2 + Gemfile.lock | 48 +++---- java-buildpack.iml | 30 ++--- lib/java_buildpack/buildpack.rb | 1 + .../container/tomcat/tomcat_geode_store.rb | 2 + .../framework/app_dynamics_agent.rb | 1 + .../framework/container_security_provider.rb | 1 + .../framework/dyadic_ekm_security_provider.rb | 2 +- .../framework/java_memory_assistant/agent.rb | 2 + .../framework/multi_buildpack.rb | 1 + .../framework/riverbed_appinternals_agent.rb | 1 + .../framework/sky_walking_agent.rb | 1 + .../framework/spring_insight.rb | 2 + lib/java_buildpack/jre/ibm_jre_initializer.rb | 5 + .../jre/open_jdk_like_security_providers.rb | 2 + lib/java_buildpack/logging/logger_factory.rb | 2 + .../repository/repository_index.rb | 1 + .../util/cache/application_cache.rb | 1 + .../util/cache/download_cache.rb | 2 + lib/java_buildpack/util/colorize.rb | 21 +++ .../util/configuration_utils.rb | 2 + lib/java_buildpack/util/filtering_pathname.rb | 5 +- .../util/find_single_directory.rb | 4 +- lib/java_buildpack/util/play/factory.rb | 1 + lib/java_buildpack/util/play/post22_dist.rb | 2 - lib/java_buildpack/util/start_script.rb | 4 +- lib/java_buildpack/util/tokenized_version.rb | 3 + rakelib/dependency_cache_task.rb | 2 +- spec/java_buildpack/buildpack_version_spec.rb | 2 +- .../component/additional_libraries_spec.rb | 2 +- .../component/application_spec.rb | 2 +- .../component/extension_directories_spec.rb | 2 +- .../component/immutable_java_home_spec.rb | 4 +- .../component/mutable_java_home_spec.rb | 16 +-- .../java_buildpack/component/services_spec.rb | 120 +++++++++--------- spec/java_buildpack/container/tomcat_spec.rb | 6 +- .../framework/java_memory_assistant_spec.rb | 2 +- spec/java_buildpack/jre/ibm_jre_spec.rb | 2 +- .../jre/open_jdk_like_jre_spec.rb | 4 +- spec/java_buildpack/jre/open_jdk_like_spec.rb | 2 +- .../logging/logger_factory_spec.rb | 2 +- .../util/cache/cached_file_spec.rb | 12 +- .../util/cache/internet_availability_spec.rb | 20 +-- .../util/configuration_utils_spec.rb | 1 + .../util/filtering_pathname_spec.rb | 16 +-- spec/java_buildpack/util/play/base_spec.rb | 14 +- .../util/play/post22_dist_spec.rb | 18 +-- .../util/play/post22_staged_spec.rb | 22 ++-- .../util/play/pre22_dist_spec.rb | 18 +-- .../util/play/pre22_staged_spec.rb | 18 +-- .../java_buildpack/util/ratpack_utils_spec.rb | 6 +- .../util/spring_boot_utils_spec.rb | 10 +- 53 files changed, 273 insertions(+), 215 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 7a286a08da..9e5c9e1794 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,12 +2,12 @@ require: rubocop-rspec AllCops: - Include: - - '**/Rakefile' - - 'rakelib/**/*' + # Include: + # - '**/Rakefile' + # - 'rakelib/**/*' Exclude: - 'build/**/*' - - Gemfile + # - Gemfile Layout/EmptyLinesAroundBlockBody: Exclude: - 'spec/**/*.rb' @@ -36,14 +36,16 @@ Metrics/PerceivedComplexity: Max: 10 Naming/UncommunicativeMethodParamName: Enabled: false -RSpec/ExampleLength: - Max: 20 RSpec/AnyInstance: Enabled: false +RSpec/ExampleLength: + Max: 20 RSpec/ExpectOutput: Enabled: false RSpec/FilePath: Enabled: false +RSpec/MissingExampleGroupArgument: + Enabled: false RSpec/MultipleExpectations: Enabled: false RSpec/NestedGroups: @@ -54,5 +56,5 @@ Style/Documentation: Enabled: false Style/FormatStringToken: Enabled: false -Style/MethodMissing: +Style/MethodMissingSuper: Enabled: false diff --git a/Gemfile b/Gemfile index d8344bf29d..ec63e80628 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source 'https://rubygems.org' group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 532e18b9f3..1f7a766a31 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,48 +8,50 @@ GEM safe_yaml (~> 1.0.0) diff-lcs (1.3) hashdiff (0.3.7) + jaro_winkler (1.5.1) parallel (1.12.1) - parser (2.5.0.5) + parser (2.5.1.2) ast (~> 2.4.0) - powerpack (0.1.1) - public_suffix (3.0.2) + powerpack (0.1.2) + public_suffix (3.0.3) rainbow (3.0.0) rake (12.3.1) redcarpet (3.4.0) - rspec (3.7.0) - rspec-core (~> 3.7.0) - rspec-expectations (~> 3.7.0) - rspec-mocks (~> 3.7.0) - rspec-core (3.7.1) - rspec-support (~> 3.7.0) - rspec-expectations (3.7.0) + rspec (3.8.0) + rspec-core (~> 3.8.0) + rspec-expectations (~> 3.8.0) + rspec-mocks (~> 3.8.0) + rspec-core (3.8.0) + rspec-support (~> 3.8.0) + rspec-expectations (3.8.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.7.0) - rspec-mocks (3.7.0) + rspec-support (~> 3.8.0) + rspec-mocks (3.8.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.7.0) - rspec-support (3.7.1) - rubocop (0.54.0) + rspec-support (~> 3.8.0) + rspec-support (3.8.0) + rubocop (0.59.1) + jaro_winkler (~> 1.5.1) parallel (~> 1.10) - parser (>= 2.5) + parser (>= 2.5, != 2.5.1.1) powerpack (~> 0.1) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.24.0) - rubocop (>= 0.53.0) - ruby-progressbar (1.9.0) - rubyzip (1.2.1) + rubocop-rspec (1.29.1) + rubocop (>= 0.58.0) + ruby-progressbar (1.10.0) + rubyzip (1.2.2) safe_yaml (1.0.4) tee (1.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - unicode-display_width (1.3.0) - webmock (3.3.0) + unicode-display_width (1.4.0) + webmock (3.4.2) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - yard (0.9.12) + yard (0.9.16) PLATFORMS ruby diff --git a/java-buildpack.iml b/java-buildpack.iml index 1ccd43a5a1..01930c6c66 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -274,27 +274,27 @@ - - - + + + - - - - - - - - - + + + + + + + + + - - - + + + diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index efa8b55074..2dc7b65251 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -168,6 +168,7 @@ def detection(type, components, unique) end raise "Application can be run by more than one #{type}: #{names detected}" if unique && detected.size > 1 + [detected, tags] end diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index fe3f17b95f..3e603973c6 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -30,6 +30,7 @@ class TomcatGeodeStore < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile return unless supports? + download_tar(false, tomcat_lib, tar_name) mutate_context mutate_server @@ -39,6 +40,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release return unless supports? + credentials = @application.services.find_service(FILTER, KEY_LOCATORS, KEY_USERS)['credentials'] user = credentials[KEY_USERS].find { |u| cluster_operator?(u) } diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 8d70129d29..f68ca3da60 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -79,6 +79,7 @@ def account_name(java_opts, credentials) def host_name(java_opts, credentials) host_name = credentials['host-name'] raise "'host-name' credential must be set" unless host_name + java_opts.add_system_property 'appdynamics.controller.hostName', host_name end diff --git a/lib/java_buildpack/framework/container_security_provider.rb b/lib/java_buildpack/framework/container_security_provider.rb index 0a6609e4b9..adfca5c917 100644 --- a/lib/java_buildpack/framework/container_security_provider.rb +++ b/lib/java_buildpack/framework/container_security_provider.rb @@ -44,6 +44,7 @@ def release end return if trust_manager_enabled.nil? + @droplet.java_opts.add_system_property 'org.cloudfoundry.security.trustmanager.enabled', trust_manager_enabled end diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index 7a6642dad6..f8880cf723 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -107,7 +107,7 @@ def write_conf(servers, send_timeout, recv_timeout, retries) recv_timeout = #{recv_timeout} retries = #{retries} ha_mode_standby = 1 -CONFIG + CONFIG end end diff --git a/lib/java_buildpack/framework/java_memory_assistant/agent.rb b/lib/java_buildpack/framework/java_memory_assistant/agent.rb index 752b517819..57cc487208 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/agent.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/agent.rb @@ -77,6 +77,7 @@ def supports? def add_system_prop_if_config_present(config_entry, system_property_name) return unless @configuration.key?(config_entry) + @droplet.java_opts.add_system_property(system_property_name, @configuration[config_entry]) end @@ -87,6 +88,7 @@ def log_level def normalized_log_level normalized_log_level = LOG_LEVEL_MAPPING[log_level.upcase] raise "Invalid value of the 'log_level' property: '#{log_level}'" unless normalized_log_level + normalized_log_level end diff --git a/lib/java_buildpack/framework/multi_buildpack.rb b/lib/java_buildpack/framework/multi_buildpack.rb index 858b1ddb4c..a7982d2932 100644 --- a/lib/java_buildpack/framework/multi_buildpack.rb +++ b/lib/java_buildpack/framework/multi_buildpack.rb @@ -270,6 +270,7 @@ def config_file(dep_directory) def contributions_message(contributions) return if contributions.compact.empty? + " contributed to: #{contributions.flatten.compact.sort.join(', ')}" end diff --git a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb index 988a1abd71..adce6ea2ce 100644 --- a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb +++ b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb @@ -44,6 +44,7 @@ def release @droplet.java_opts.add_agentpath(agent_path) return unless rvbd_moniker(credentials) + @droplet.java_opts.add_system_property('riverbed.moniker', rvbd_moniker(credentials)) end diff --git a/lib/java_buildpack/framework/sky_walking_agent.rb b/lib/java_buildpack/framework/sky_walking_agent.rb index e106f901d4..0ab38380c9 100644 --- a/lib/java_buildpack/framework/sky_walking_agent.rb +++ b/lib/java_buildpack/framework/sky_walking_agent.rb @@ -62,6 +62,7 @@ def supports? def servers(java_opts, credentials) servers = credentials['servers'] raise "'servers' credential must be set" unless servers + java_opts.add_system_property 'skywalking.collector.servers', servers end diff --git a/lib/java_buildpack/framework/spring_insight.rb b/lib/java_buildpack/framework/spring_insight.rb index fd48bee3c5..49d3df93ea 100644 --- a/lib/java_buildpack/framework/spring_insight.rb +++ b/lib/java_buildpack/framework/spring_insight.rb @@ -172,6 +172,7 @@ def supports? def uber_agent_zip(location) candidates = Pathname.glob(location + 'springsource-insight-uber-agent-*.zip') raise 'There was not exactly one Uber Agent zip' if candidates.size != 1 + candidates[0] end @@ -186,6 +187,7 @@ def weaver_jar def transport_plugin(root) return root + 'transport/http/insight-agent-http-*.jar' if http_transport? return root + 'transport/rabbitmq/insight-agent-rabbitmq-*.jar' if rabbit_transport? + (root + 'transport/activemq/insight-agent-activemq-*.jar') if active_transport? end diff --git a/lib/java_buildpack/jre/ibm_jre_initializer.rb b/lib/java_buildpack/jre/ibm_jre_initializer.rb index 8607644e29..09120ed9b0 100644 --- a/lib/java_buildpack/jre/ibm_jre_initializer.rb +++ b/lib/java_buildpack/jre/ibm_jre_initializer.rb @@ -109,8 +109,10 @@ def heap_ratio def memory_limit_finder memory_limit = ENV['MEMORY_LIMIT'] return nil unless memory_limit + memory_limit_size = memory_size_bytes(memory_limit) raise "Invalid negative $MEMORY_LIMIT #{memory_limit}" if memory_limit_size.negative? + memory_limit_size end @@ -119,9 +121,11 @@ def memory_size_bytes(size) bytes = 0 else raise "Invalid memory size '#{size}'" if !size || size.length < 2 + unit = size[-1] value = size[0..-2] raise "Invalid memory size '#{size}'" unless check_is_integer? value + value = size.to_i # store the bytes bytes = calculate_bytes(unit, value) @@ -173,6 +177,7 @@ def minified_size_calculator(order, char) def heap_ratio_verification(ratio) raise 'Invalid heap ratio' unless ratio.is_a? Numeric raise 'heap ratio cannot be greater than 100%' unless ratio <= 1 + ratio end diff --git a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb index 492e807141..0804a5d442 100644 --- a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb +++ b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb @@ -39,6 +39,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release return if @droplet.java_home.java_9_or_later? + @droplet.extension_directories << java_security.parent.parent + 'ext' unless java_security.nil? end @@ -67,6 +68,7 @@ def java_security return java_9_security if @droplet.java_home.java_9_or_later? && java_9_security.exist? return jre_security if jre_security.exist? return server_jre_security if server_jre_security.exist? + nil end diff --git a/lib/java_buildpack/logging/logger_factory.rb b/lib/java_buildpack/logging/logger_factory.rb index f58934c68f..15668e9c7b 100644 --- a/lib/java_buildpack/logging/logger_factory.rb +++ b/lib/java_buildpack/logging/logger_factory.rb @@ -66,6 +66,7 @@ def setup(app_dir) def get_logger(klass) @monitor.synchronize do raise "Attempted to get Logger for #{short_class(klass)} before initialization" unless @initialized + DelegatingLogger.new wrapped_short_class(klass), @delegates end end @@ -77,6 +78,7 @@ def get_logger(klass) def log_file @monitor.synchronize do raise 'Attempted to get log file before initialization' unless @initialized + @log_file end end diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 48133fc490..84298e7587 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -52,6 +52,7 @@ def initialize(repository_root) def find_item(version) found_version = VersionResolver.resolve(version, @index.keys) raise "No version resolvable for '#{version}' in #{@index.keys.join(', ')}" if found_version.nil? + uri = @index[found_version.to_s] [found_version, uri] end diff --git a/lib/java_buildpack/util/cache/application_cache.rb b/lib/java_buildpack/util/cache/application_cache.rb index f2ebab0c8f..90264ec521 100644 --- a/lib/java_buildpack/util/cache/application_cache.rb +++ b/lib/java_buildpack/util/cache/application_cache.rb @@ -52,6 +52,7 @@ def initialize logger = Logging::LoggerFactory.instance.get_logger ApplicationCache raise 'Application cache directory is undefined' unless self.class.available? + logger.debug { "Application Cache Directory: #{self.class.application_cache_directory}" } super(Pathname.new(self.class.application_cache_directory), CACHED_RESOURCES_DIRECTORY) diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 793374122d..32edb06765 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -77,6 +77,7 @@ def get(uri, &block) end raise "Unable to find cached file for #{uri.sanitize_uri}" unless cached_file + cached_file.cached(File::RDONLY | File::BINARY, downloaded, &block) end @@ -175,6 +176,7 @@ def attempt_update(cached_file, http, uri) def ca_file(http_options) return unless CA_FILE.exist? + http_options[:ca_file] = CA_FILE.to_s @logger.debug { "Adding additional CA certificates from #{CA_FILE}" } end diff --git a/lib/java_buildpack/util/colorize.rb b/lib/java_buildpack/util/colorize.rb index e48975ea9b..887ce18103 100644 --- a/lib/java_buildpack/util/colorize.rb +++ b/lib/java_buildpack/util/colorize.rb @@ -26,126 +26,147 @@ class << self # Sets the string to bold def bold return self unless self.class.color_enabled + "\e[1m#{self}\e[22m" end # Sets the string to italic def italic return self unless self.class.color_enabled + "\e[3m#{self}\e[23m" end # Sets the string to underlined def underline return self unless self.class.color_enabled + "\e[4m#{self}\e[24m" end # Sets the string to blink def blink return self unless self.class.color_enabled + "\e[5m#{self}\e[25m" end # Sets the string reverse the current colors def reverse_color return self unless self.class.color_enabled + "\e[7m#{self}\e[27m" end # Sets the string to black def black return self unless self.class.color_enabled + "\e[30m#{self}\e[0m" end # Sets the string to red def red return self unless self.class.color_enabled + "\e[31m#{self}\e[0m" end # Sets the string to green def green return self unless self.class.color_enabled + "\e[32m#{self}\e[0m" end # Sets the string to yellow def yellow return self unless self.class.color_enabled + "\e[33m#{self}\e[0m" end # Sets the string to blue def blue return self unless self.class.color_enabled + "\e[34m#{self}\e[0m" end # Sets the string to magenta def magenta return self unless self.class.color_enabled + "\e[35m#{self}\e[0m" end # Sets the string to cyan def cyan return self unless self.class.color_enabled + "\e[36m#{self}\e[0m" end # Sets the string to white def white return self unless self.class.color_enabled + "\e[37m#{self}\e[0m" end # Sets the string background to black def bg_black return self unless self.class.color_enabled + "\e[40m#{self}\e[0m" end # Sets the string background to red def bg_red return self unless self.class.color_enabled + "\e[41m#{self}\e[0m" end # Sets the string background to green def bg_green return self unless self.class.color_enabled + "\e[42m#{self}\e[0m" end # Sets the string background to yellow def bg_yellow return self unless self.class.color_enabled + "\e[43m#{self}\e[0m" end # Sets the string background to blue def bg_blue return self unless self.class.color_enabled + "\e[44m#{self}\e[0m" end # Sets the string background to magenta def bg_magenta return self unless self.class.color_enabled + "\e[45m#{self}\e[0m" end # Sets the string background to cyan def bg_cyan return self unless self.class.color_enabled + "\e[46m#{self}\e[0m" end # Sets the string background to white def bg_white return self unless self.class.color_enabled + "\e[47m#{self}\e[0m" end diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index e8e8e8dbe7..46fee0fbee 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -105,6 +105,7 @@ def header(file) f.each do |line| break if line =~ /^---/ raise unless line =~ /^#/ || line =~ /^$/ + header << line end end @@ -154,6 +155,7 @@ def do_merge(hash_v1, hash_v2, should_log) def do_resolve_value(key, v1, v2, should_log) return do_merge(v1, v2, should_log) if v1.is_a?(Hash) && v2.is_a?(Hash) return v2 if !v1.is_a?(Hash) && !v2.is_a?(Hash) + logger.warn { "User config value for '#{key}' is not valid, must be of a similar type" } if should_log v1 end diff --git a/lib/java_buildpack/util/filtering_pathname.rb b/lib/java_buildpack/util/filtering_pathname.rb index 466ad15a80..4abc96479a 100644 --- a/lib/java_buildpack/util/filtering_pathname.rb +++ b/lib/java_buildpack/util/filtering_pathname.rb @@ -143,9 +143,9 @@ def glob(flags = 0) end end - attr_reader :pathname + protected - protected :pathname + attr_reader :pathname private @@ -224,6 +224,7 @@ def visible(entry) def filter(pathname) raise 'Non-absolute pathname' unless pathname.absolute? + @filter.call(pathname.cleanpath) end diff --git a/lib/java_buildpack/util/find_single_directory.rb b/lib/java_buildpack/util/find_single_directory.rb index 26d713b471..edae7d0b63 100644 --- a/lib/java_buildpack/util/find_single_directory.rb +++ b/lib/java_buildpack/util/find_single_directory.rb @@ -20,6 +20,8 @@ module JavaBuildpack module Util + module_function + # Find the single directory in the root of the droplet # # @return [Pathname, nil] the single directory in the root of the droplet, otherwise +nil+ @@ -28,7 +30,5 @@ def find_single_directory roots.size == 1 ? roots.first : nil end - module_function :find_single_directory - end end diff --git a/lib/java_buildpack/util/play/factory.rb b/lib/java_buildpack/util/play/factory.rb index 13163296da..a772eb5200 100644 --- a/lib/java_buildpack/util/play/factory.rb +++ b/lib/java_buildpack/util/play/factory.rb @@ -45,6 +45,7 @@ def create(droplet) ].select(&:supports?) raise "Play Framework application version cannot be determined: #{candidates}" if candidates.size > 1 + candidates.empty? ? nil : candidates.first end diff --git a/lib/java_buildpack/util/play/post22_dist.rb b/lib/java_buildpack/util/play/post22_dist.rb index 1ca9ef5e24..3571c7ef51 100644 --- a/lib/java_buildpack/util/play/post22_dist.rb +++ b/lib/java_buildpack/util/play/post22_dist.rb @@ -26,8 +26,6 @@ class Post22Dist < Post22 alias root find_single_directory - protected :root - end end diff --git a/lib/java_buildpack/util/start_script.rb b/lib/java_buildpack/util/start_script.rb index f5d77ff94d..3a4a08058e 100644 --- a/lib/java_buildpack/util/start_script.rb +++ b/lib/java_buildpack/util/start_script.rb @@ -20,6 +20,8 @@ module JavaBuildpack module Util + module_function + # Find a start script relative to a root directory. A start script is defined as existing in the +bin/+ directory # and being either the only file, or the only file with a counterpart named +.bat+ # @@ -37,7 +39,5 @@ def start_script(root) end end - module_function :start_script - end end diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index c9c82d69c0..8ce0c2839f 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -90,6 +90,7 @@ def major_or_minor_and_tail(s) else raise "Invalid version '#{s}': must not end in '.'" if s[-1] == '.' raise "Invalid version '#{s}': missing component" if s =~ /\.[\._]/ + tokens = s.match(/^([^\.]+)(?:\.(.*))?/) major_or_minor, tail = tokens[1..-1] @@ -106,6 +107,7 @@ def micro_and_qualifier(s) qualifier = nil else raise "Invalid version '#{s}': must not end in '_'" if s[-1] == '_' + tokens = s.match(/^([^\_]+)(?:_(.*))?/) micro, qualifier = tokens[1..-1] @@ -147,6 +149,7 @@ def validate(allow_wildcards) end raise "Invalid version '#{@version}': no characters are allowed after a wildcard" if wildcarded && value + wildcarded = true if !value.nil? && value.end_with?(WILDCARD) end raise "Invalid version '#{@version}': missing component" if !wildcarded && compact.length < 3 diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index d3ff237b68..bc72a5f388 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -182,7 +182,7 @@ def get_from_cache(configuration, index_configuration, uris) def pin_version(old_configuration, version) component_id = old_configuration['component_id'] sub_component_id = old_configuration['sub_component_id'] - rake_output_message "Pinning #{sub_component_id ? sub_component_id : component_id} version to #{version}" + rake_output_message "Pinning #{sub_component_id || component_id} version to #{version}" configuration_to_update = JavaBuildpack::Util::ConfigurationUtils.load(component_id, false, true) update_configuration(configuration_to_update, version, sub_component_id) JavaBuildpack::Util::ConfigurationUtils.write(component_id, configuration_to_update) diff --git a/spec/java_buildpack/buildpack_version_spec.rb b/spec/java_buildpack/buildpack_version_spec.rb index e1511279ae..28669a26c4 100644 --- a/spec/java_buildpack/buildpack_version_spec.rb +++ b/spec/java_buildpack/buildpack_version_spec.rb @@ -128,7 +128,7 @@ it 'picks up offline from the environment' do allow_any_instance_of(described_class).to receive(:system).with('which git > /dev/null').and_return(false) - expect(buildpack_version.offline).to be + expect(buildpack_version.offline).to be_truthy end end diff --git a/spec/java_buildpack/component/additional_libraries_spec.rb b/spec/java_buildpack/component/additional_libraries_spec.rb index cd62313ef1..2b4348830d 100644 --- a/spec/java_buildpack/component/additional_libraries_spec.rb +++ b/spec/java_buildpack/component/additional_libraries_spec.rb @@ -47,7 +47,7 @@ it 'renders empty string if classpath is empty' do additional_libraries.clear - expect(additional_libraries.as_classpath).not_to be + expect(additional_libraries.as_classpath).not_to be_truthy end it 'symbolically links additional libraries' do diff --git a/spec/java_buildpack/component/application_spec.rb b/spec/java_buildpack/component/application_spec.rb index 5984e10185..447a3ac828 100644 --- a/spec/java_buildpack/component/application_spec.rb +++ b/spec/java_buildpack/component/application_spec.rb @@ -70,7 +70,7 @@ end it 'returns a parsed version of VCAP_SERVICES as services' do - expect(application.services.find_service(/test-service/)).to be + expect(application.services.find_service(/test-service/)).to be_truthy end end diff --git a/spec/java_buildpack/component/extension_directories_spec.rb b/spec/java_buildpack/component/extension_directories_spec.rb index 9d500fd7dc..99fa1c7650 100644 --- a/spec/java_buildpack/component/extension_directories_spec.rb +++ b/spec/java_buildpack/component/extension_directories_spec.rb @@ -46,7 +46,7 @@ it 'renders empty string if path is empty' do extension_directories.clear - expect(extension_directories.as_paths).not_to be + expect(extension_directories.as_paths).not_to be_truthy end end diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index c51cc9d5b9..b8fbbb25c9 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -45,11 +45,11 @@ end it 'returns the delegate Java 8 or later' do - expect(immutable_java_home.java_8_or_later?).to be + expect(immutable_java_home).to be_java_8_or_later end it 'returns the delegate Java 9 or later' do - expect(immutable_java_home.java_9_or_later?).to be + expect(immutable_java_home).to be_java_9_or_later end end diff --git a/spec/java_buildpack/component/mutable_java_home_spec.rb b/spec/java_buildpack/component/mutable_java_home_spec.rb index 74eee4561d..a189cfc27f 100644 --- a/spec/java_buildpack/component/mutable_java_home_spec.rb +++ b/spec/java_buildpack/component/mutable_java_home_spec.rb @@ -40,42 +40,42 @@ it 'recognizes Java 6 as earlier than Java 8' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.6.0') - expect(mutable_java_home.java_8_or_later?).not_to be + expect(mutable_java_home).not_to be_java_8_or_later end it 'recognizes Java 7 as earlier than Java 8' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0') - expect(mutable_java_home.java_8_or_later?).not_to be + expect(mutable_java_home).not_to be_java_8_or_later end it 'recognizes Java 8 as later than or equal to Java 8' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0') - expect(mutable_java_home.java_8_or_later?).to be + expect(mutable_java_home).to be_java_8_or_later end it 'recognizes Java 9 as later than or equal to Java 8' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') - expect(mutable_java_home.java_8_or_later?).to be + expect(mutable_java_home).to be_java_8_or_later end it 'recognizes Java 6 as earlier than Java 9' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.6.0') - expect(mutable_java_home.java_9_or_later?).not_to be + expect(mutable_java_home).not_to be_java_9_or_later end it 'recognizes Java 7 as earlier than Java 9' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.7.0') - expect(mutable_java_home.java_9_or_later?).not_to be + expect(mutable_java_home).not_to be_java_9_or_later end it 'recognizes Java 8 as earlier than Java 9' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0') - expect(mutable_java_home.java_9_or_later?).not_to be + expect(mutable_java_home).not_to be_java_9_or_later end it 'recognizes Java 9 as later than or equal to Java 9' do mutable_java_home.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') - expect(mutable_java_home.java_9_or_later?).to be + expect(mutable_java_home).to be_java_9_or_later end end diff --git a/spec/java_buildpack/component/services_spec.rb b/spec/java_buildpack/component/services_spec.rb index 5efbd25443..abfa5cc6a2 100644 --- a/spec/java_buildpack/component/services_spec.rb +++ b/spec/java_buildpack/component/services_spec.rb @@ -168,48 +168,48 @@ end it 'returns false from one_service? if there is no service that matches' do - expect(services.one_service?('bad-test')).not_to be - expect(services.one_service?(/bad-test/)).not_to be + expect(services).not_to be_one_service('bad-test') + expect(services).not_to be_one_service(/bad-test/) end it 'returns true from one_service? if there is a matching name' do - expect(services.one_service?('test-name')).to be - expect(services.one_service?(/test-name/)).to be + expect(services).to be_one_service('test-name') + expect(services).to be_one_service(/test-name/) end it 'returns true from one_service? if there is a matching label' do - expect(services.one_service?('test-label')).to be - expect(services.one_service?(/test-label/)).to be + expect(services).to be_one_service('test-label') + expect(services).to be_one_service(/test-label/) end it 'returns true from one_service? if there is a matching tag' do - expect(services.one_service?('test-tag')).to be - expect(services.one_service?(/test-tag/)).to be + expect(services).to be_one_service('test-tag') + expect(services).to be_one_service(/test-tag/) end it 'returns false from one_service? if there is a matching service without required credentials' do - expect(services.one_service?('test-tag', 'bad-credential')).not_to be - expect(services.one_service?(/test-tag/, 'bad-credential')).not_to be + expect(services).not_to be_one_service('test-tag', 'bad-credential') + expect(services).not_to be_one_service(/test-tag/, 'bad-credential') end it 'returns true from one_service? if there is a matching service with required credentials' do - expect(services.one_service?('test-tag', 'uri')).to be - expect(services.one_service?(/test-tag/, 'uri')).to be + expect(services).to be_one_service('test-tag', 'uri') + expect(services).to be_one_service(/test-tag/, 'uri') end it 'returns true from one_service? if there is a matching service with one required group credentials' do - expect(services.one_service?('test-tag', %w[uri other])).to be - expect(services.one_service?(/test-tag/, %w[uri other])).to be + expect(services).to be_one_service('test-tag', %w[uri other]) + expect(services).to be_one_service(/test-tag/, %w[uri other]) end it 'returns true from one_service? if there is a matching service with two required group credentials' do - expect(services.one_service?('test-tag', %w[h1 h2])).to be - expect(services.one_service?(/test-tag/, %w[h1 h2])).to be + expect(services).to be_one_service('test-tag', %w[h1 h2]) + expect(services).to be_one_service(/test-tag/, %w[h1 h2]) end it 'returns false from one_service? if there is a matching service with no required group credentials' do - expect(services.one_service?('test-tag', %w[foo bar])).not_to be - expect(services.one_service?(/test-tag/, %w[foo bar])).not_to be + expect(services).not_to be_one_service('test-tag', %w[foo bar]) + expect(services).not_to be_one_service(/test-tag/, %w[foo bar]) end end @@ -223,48 +223,48 @@ end it 'returns false from one_service? if there is no service that matches' do - expect(services.one_service?('bad-test')).not_to be - expect(services.one_service?(/bad-test/)).not_to be + expect(services).not_to be_one_service('bad-test') + expect(services).not_to be_one_service(/bad-test/) end it 'returns true from one_service? if there is a matching name' do - expect(services.one_service?('test-name')).to be - expect(services.one_service?(/test-name/)).to be + expect(services).to be_one_service('test-name') + expect(services).to be_one_service(/test-name/) end it 'returns true from one_service? if there is a matching label' do - expect(services.one_service?('test-label')).to be - expect(services.one_service?(/test-label/)).to be + expect(services).to be_one_service('test-label') + expect(services).to be_one_service(/test-label/) end it 'returns true from one_service? if there is a matching tag' do - expect(services.one_service?('test-tag')).to be - expect(services.one_service?(/test-tag/)).to be + expect(services).to be_one_service('test-tag') + expect(services).to be_one_service(/test-tag/) end it 'returns false from one_service? if there is a matching service without required credentials' do - expect(services.one_service?('test-tag', 'bad-credential')).not_to be - expect(services.one_service?(/test-tag/, 'bad-credential')).not_to be + expect(services).not_to be_one_service('test-tag', 'bad-credential') + expect(services).not_to be_one_service(/test-tag/, 'bad-credential') end it 'returns true from one_service? if there is a matching service with required credentials' do - expect(services.one_service?('test-tag', 'uri')).to be - expect(services.one_service?(/test-tag/, 'uri')).to be + expect(services).to be_one_service('test-tag', 'uri') + expect(services).to be_one_service(/test-tag/, 'uri') end it 'returns true from one_service? if there is a matching service with one required group credentials' do - expect(services.one_service?('test-tag', %w[uri other])).to be - expect(services.one_service?(/test-tag/, %w[uri other])).to be + expect(services).to be_one_service('test-tag', %w[uri other]) + expect(services).to be_one_service(/test-tag/, %w[uri other]) end it 'returns true from one_service? if there is a matching service with two required group credentials' do - expect(services.one_service?('test-tag', %w[h1 h2])).to be - expect(services.one_service?(/test-tag/, %w[h1 h2])).to be + expect(services).to be_one_service('test-tag', %w[h1 h2]) + expect(services).to be_one_service(/test-tag/, %w[h1 h2]) end it 'returns false from one_service? if there is a matching service with no required group credentials' do - expect(services.one_service?('test-tag', %w[foo bar])).not_to be - expect(services.one_service?(/test-tag/, %w[foo bar])).not_to be + expect(services).not_to be_one_service('test-tag', %w[foo bar]) + expect(services).not_to be_one_service(/test-tag/, %w[foo bar]) end end @@ -280,18 +280,18 @@ end it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do - expect(services.one_volume_service?('test-name')).not_to be - expect(services.one_volume_service?(/test-name/)).not_to be + expect(services).not_to be_one_volume_service('test-name') + expect(services).not_to be_one_volume_service(/test-name/) end it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do - expect(services.one_volume_service?('test-label')).not_to be - expect(services.one_volume_service?(/test-label/)).not_to be + expect(services).not_to be_one_volume_service('test-label') + expect(services).not_to be_one_volume_service(/test-label/) end it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do - expect(services.one_volume_service?('test-tag')).not_to be - expect(services.one_volume_service?(/test-tag/)).not_to be + expect(services).not_to be_one_volume_service('test-tag') + expect(services).not_to be_one_volume_service(/test-tag/) end end @@ -304,18 +304,18 @@ end it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do - expect(services.one_volume_service?('test-name')).not_to be - expect(services.one_volume_service?(/test-name/)).not_to be + expect(services).not_to be_one_volume_service('test-name') + expect(services).not_to be_one_volume_service(/test-name/) end it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do - expect(services.one_volume_service?('test-label')).not_to be - expect(services.one_volume_service?(/test-label/)).not_to be + expect(services).not_to be_one_volume_service('test-label') + expect(services).not_to be_one_volume_service(/test-label/) end it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do - expect(services.one_volume_service?('test-tag')).not_to be - expect(services.one_volume_service?(/test-tag/)).not_to be + expect(services).not_to be_one_volume_service('test-tag') + expect(services).not_to be_one_volume_service(/test-tag/) end end @@ -330,18 +330,18 @@ end it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do - expect(services.one_volume_service?('test-name')).to be - expect(services.one_volume_service?(/test-name/)).to be + expect(services).to be_one_volume_service('test-name') + expect(services).to be_one_volume_service(/test-name/) end it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do - expect(services.one_volume_service?('test-label')).to be - expect(services.one_volume_service?(/test-label/)).to be + expect(services).to be_one_volume_service('test-label') + expect(services).to be_one_volume_service(/test-label/) end it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do - expect(services.one_volume_service?('test-tag')).to be - expect(services.one_volume_service?(/test-tag/)).to be + expect(services).to be_one_volume_service('test-tag') + expect(services).to be_one_volume_service(/test-tag/) end end @@ -359,18 +359,18 @@ end it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do - expect(services.one_volume_service?('test-name')).not_to be - expect(services.one_volume_service?(/test-name/)).not_to be + expect(services).not_to be_one_volume_service('test-name') + expect(services).not_to be_one_volume_service(/test-name/) end it 'returns true from one_volume_service? if there is a matching label and empty volume_mounts' do - expect(services.one_volume_service?('test-label')).not_to be - expect(services.one_volume_service?(/test-label/)).not_to be + expect(services).not_to be_one_volume_service('test-label') + expect(services).not_to be_one_volume_service(/test-label/) end it 'returns false from one_volume_service? if there is a matching tag and empty volume_mounts' do - expect(services.one_volume_service?('test-tag')).not_to be - expect(services.one_volume_service?(/test-tag/)).not_to be + expect(services).not_to be_one_volume_service('test-tag') + expect(services).not_to be_one_volume_service(/test-tag/) end end diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index e0f9d40b41..6a8774a676 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -59,19 +59,19 @@ it 'detects WEB-INF', app_fixture: 'container_tomcat' do - expect(component.supports?).to be + expect(component).to be_supports end it 'does not detect when WEB-INF is absent', app_fixture: 'container_main' do - expect(component.supports?).not_to be + expect(component).not_to be_supports end it 'does not detect when WEB-INF is present in a Java main application', app_fixture: 'container_main_with_web_inf' do - expect(component.supports?).not_to be + expect(component).not_to be_supports end it 'creates submodules' do diff --git a/spec/java_buildpack/framework/java_memory_assistant_spec.rb b/spec/java_buildpack/framework/java_memory_assistant_spec.rb index 4d2caa21e8..d09b428d31 100644 --- a/spec/java_buildpack/framework/java_memory_assistant_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant_spec.rb @@ -37,7 +37,7 @@ end it 'does not activate submodules if it is disabled in the configuration' do - expect(component.detect).not_to be + expect(component.detect).not_to be_truthy end end diff --git a/spec/java_buildpack/jre/ibm_jre_spec.rb b/spec/java_buildpack/jre/ibm_jre_spec.rb index 3c4e750704..88c43f5754 100644 --- a/spec/java_buildpack/jre/ibm_jre_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_spec.rb @@ -39,7 +39,7 @@ let(:jvmkill_agent_configuration) { {} } it 'supports anyway' do - expect(component.supports?).to be + expect(component).to be_supports end it 'creates IbmJreInitializer instance' do diff --git a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index 908258335f..b035bde48c 100644 --- a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -58,8 +58,8 @@ component.detect component.compile - expect(networking.networkaddress_cache_ttl).not_to be - expect(networking.networkaddress_cache_negative_ttl).not_to be + expect(networking.networkaddress_cache_ttl).not_to be_truthy + expect(networking.networkaddress_cache_negative_ttl).not_to be_truthy end it 'disables dns caching if BOSH DNS', diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index 5d6eed5198..002fb46905 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -48,7 +48,7 @@ let(:memory_calculator_configuration) { { 'stack_threads' => '200' } } it 'always supports' do - expect(component.supports?).to be + expect(component).to be_supports end it 'creates submodules' do diff --git a/spec/java_buildpack/logging/logger_factory_spec.rb b/spec/java_buildpack/logging/logger_factory_spec.rb index a7c70829df..31572ef881 100644 --- a/spec/java_buildpack/logging/logger_factory_spec.rb +++ b/spec/java_buildpack/logging/logger_factory_spec.rb @@ -28,7 +28,7 @@ let(:logger) { described_class.instance.get_logger String } it 'maintains backwards compatibility' do - expect(described_class.get_logger(String)).to be + expect(described_class.get_logger(String)).to be_truthy end it 'logs all levels to file', diff --git a/spec/java_buildpack/util/cache/cached_file_spec.rb b/spec/java_buildpack/util/cache/cached_file_spec.rb index 70b24940db..9c72a90db4 100644 --- a/spec/java_buildpack/util/cache/cached_file_spec.rb +++ b/spec/java_buildpack/util/cache/cached_file_spec.rb @@ -49,15 +49,15 @@ end it 'does not detect cached file' do - expect(file_cache.cached?).not_to be + expect(file_cache).not_to be_cached end it 'does not detect etag file' do - expect(file_cache.etag?).not_to be + expect(file_cache).not_to be_etag end it 'does not detect last_modified file' do - expect(file_cache.last_modified?).not_to be + expect(file_cache).not_to be_last_modified end context do @@ -73,7 +73,7 @@ end it 'detects cached file' do - expect(file_cache.cached?).to be + expect(file_cache).to be_cached end it 'destroys all files' do @@ -93,7 +93,7 @@ end it 'detects etag file' do - expect(file_cache.etag?).to be + expect(file_cache).to be_etag end it 'calls the block with the content of the last_modified file' do @@ -102,7 +102,7 @@ end it 'detects last_modified file' do - expect(file_cache.last_modified?).to be + expect(file_cache).to be_last_modified end end diff --git a/spec/java_buildpack/util/cache/internet_availability_spec.rb b/spec/java_buildpack/util/cache/internet_availability_spec.rb index d7c3bc33ca..e97875c556 100644 --- a/spec/java_buildpack/util/cache/internet_availability_spec.rb +++ b/spec/java_buildpack/util/cache/internet_availability_spec.rb @@ -26,7 +26,7 @@ include_context 'with logging help' it 'uses internet by default' do - expect(described_class.instance.available?).to be + expect(described_class.instance).to be_available end context do @@ -38,7 +38,7 @@ end it 'does not use internet if remote downloads are disabled' do - expect(described_class.instance.available?).not_to be + expect(described_class.instance).not_to be_available end end @@ -47,7 +47,7 @@ described_class.instance.available false - expect(described_class.instance.available?).not_to be + expect(described_class.instance).not_to be_available expect(log_contents).not_to match(/Internet availability set to false/) end @@ -56,26 +56,26 @@ described_class.instance.available false, 'test message' - expect(described_class.instance.available?).not_to be + expect(described_class.instance).not_to be_available expect(log_contents).to match(/Internet availability set to false: test message/) end it 'temporarily sets internet unavailable' do - expect(described_class.instance.available?).to be + expect(described_class.instance).to be_available - described_class.instance.available(false) { expect(described_class.instance.available?).not_to be } + described_class.instance.available(false) { expect(described_class.instance).not_to be_available } - expect(described_class.instance.available?).to be + expect(described_class.instance).to be_available end it 'temporarily sets internet available', :disable_internet do - expect(described_class.instance.available?).not_to be + expect(described_class.instance).not_to be_available - described_class.instance.available(true) { expect(described_class.instance.available?).to be } + described_class.instance.available(true) { expect(described_class.instance).to be_available } - expect(described_class.instance.available?).not_to be + expect(described_class.instance).not_to be_available end end diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index df80c1f77e..a7075060c7 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -134,6 +134,7 @@ def file_contents(file) File.open(file, 'r') do |f| f.each do |line| break if line =~ /^---/ + header << line end end diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index d8246f608f..9beb18b3a6 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -120,8 +120,8 @@ end it 'compares to pathnames using ==' do - expect((filtering_target + 'good') == (app_dir + 'good')).to be - expect((filtering_target + 'bad') == (app_dir + 'bad')).to be + expect((filtering_target + 'good') == (app_dir + 'good')).to be_truthy + expect((filtering_target + 'bad') == (app_dir + 'bad')).to be_truthy end # rubocop:disable Lint/UselessComparison, Style/CaseEquality @@ -134,18 +134,18 @@ end it 'compares to filtering pathnames using ==' do - expect((filtering_target + 'good') == (filtering_target + 'good')).to be - expect((filtering_target + 'bad') == (filtering_target + 'bad')).to be + expect((filtering_target + 'good') == (filtering_target + 'good')).to be_truthy + expect((filtering_target + 'bad') == (filtering_target + 'bad')).to be_truthy end it 'compares to pathnames using ===' do - expect((filtering_target + 'good') === (app_dir + 'good')).to be - expect((filtering_target + 'bad') === (app_dir + 'bad')).to be + expect((filtering_target + 'good') === (app_dir + 'good')).to be_truthy + expect((filtering_target + 'bad') === (app_dir + 'bad')).to be_truthy end it 'compares to filtering pathnames using ===' do - expect((filtering_target + 'good') === (filtering_target + 'good')).to be - expect((filtering_target + 'bad') === (filtering_target + 'bad')).to be + expect((filtering_target + 'good') === (filtering_target + 'good')).to be_truthy + expect((filtering_target + 'bad') === (filtering_target + 'bad')).to be_truthy end # rubocop:enable Lint/UselessComparison, Style/CaseEquality diff --git a/spec/java_buildpack/util/play/base_spec.rb b/spec/java_buildpack/util/play/base_spec.rb index c2f75c5123..831fbb7096 100644 --- a/spec/java_buildpack/util/play/base_spec.rb +++ b/spec/java_buildpack/util/play/base_spec.rb @@ -28,13 +28,13 @@ it 'does not support with no start script' do allow(play).to receive(:start_script).and_return nil - expect(play.supports?).not_to be + expect(play).not_to be_supports end it 'does not support with a non-existent start script' do allow(play).to receive(:start_script).and_return(droplet.root + 'bin/start') - expect(play.supports?).not_to be + expect(play).not_to be_supports end it 'does not support with no play JAR' do @@ -44,7 +44,7 @@ FileUtils.mkdir_p app_dir + 'bin' FileUtils.touch app_dir + 'bin/start' - expect(play.supports?).not_to be + expect(play).not_to be_supports end it 'raises error if augment_classpath method is unimplemented' do @@ -78,7 +78,7 @@ end it 'supports application' do - expect(play.supports?).to be + expect(play).to be_supports end it 'returns a version' do @@ -94,9 +94,9 @@ end it 'determines whether or not certain JARs are present in the lib directory' do - expect(play.jar?(/so.*st.jar/)).to be - expect(play.jar?(/some.test.jar/)).to be - expect(play.jar?(/nosuch.jar/)).not_to be + expect(play).to be_jar(/so.*st.jar/) + expect(play).to be_jar(/some.test.jar/) + expect(play).not_to be_jar(/nosuch.jar/) end it 'replaces the bootstrap class' do diff --git a/spec/java_buildpack/util/play/post22_dist_spec.rb b/spec/java_buildpack/util/play/post22_dist_spec.rb index 5fc7ee046e..92ed5fb54b 100644 --- a/spec/java_buildpack/util/play/post22_dist_spec.rb +++ b/spec/java_buildpack/util/play/post22_dist_spec.rb @@ -27,55 +27,55 @@ let(:trigger) { described_class.new(droplet).supports? } it 'does not recognize non-applications' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.0 applications', app_fixture: 'container_play_2.0_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.1 dist applications', app_fixture: 'container_play_2.1_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.1 staged applications', app_fixture: 'container_play_2.1_staged' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a Ratpack application', app_fixture: 'container_ratpack_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a Spring Boot application', app_fixture: 'container_spring_boot_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a distZip application', app_fixture: 'container_dist_zip' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'recognizes Play 2.2 dist applications', app_fixture: 'container_play_2.2_dist' do - expect(trigger).to be + expect(trigger).to be_truthy end it 'does not recognize Play 2.2 staged applications', app_fixture: 'container_play_2.2_staged' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end end diff --git a/spec/java_buildpack/util/play/post22_staged_spec.rb b/spec/java_buildpack/util/play/post22_staged_spec.rb index 7407f202f3..b8ad8a5a45 100644 --- a/spec/java_buildpack/util/play/post22_staged_spec.rb +++ b/spec/java_buildpack/util/play/post22_staged_spec.rb @@ -27,67 +27,67 @@ let(:trigger) { described_class.new(droplet).supports? } it 'does not recognize non-applications' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.0 applications', app_fixture: 'container_play_2.0_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.1 dist applications', app_fixture: 'container_play_2.1_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.1 staged applications', app_fixture: 'container_play_2.1_staged' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.2 dist applications', app_fixture: 'container_play_2.2_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a Ratpack application', app_fixture: 'container_ratpack_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a Spring Boot application', app_fixture: 'container_spring_boot_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a distZip application', app_fixture: 'container_dist_zip' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'recognizes Play 2.2 staged applications', app_fixture: 'container_play_2.2_staged' do - expect(trigger).to be + expect(trigger).to be_truthy end it 'recognizes a Play 2.2 application with a missing .bat file if there is precisely one start script', app_fixture: 'container_play_2.2_minus_bat_file' do - expect(trigger).to be + expect(trigger).to be_truthy end it 'does not recognize a Play 2.2 application with a missing .bat file and more than one start script', app_fixture: 'container_play_2.2_ambiguous_start_script' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end end diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index 1016431463..fd34745181 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -27,55 +27,55 @@ let(:trigger) { described_class.new(droplet).supports? } it 'does not recognize non-applications' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'recognizes Play 2.0 dist applications', app_fixture: 'container_play_2.0_dist' do - expect(trigger).to be + expect(trigger).to be_truthy end it 'recognizes Play 2.1 dist applications', app_fixture: 'container_play_2.1_dist' do - expect(trigger).to be + expect(trigger).to be_truthy end it 'does not recognize Play 2.1 staged (or equivalently 2.0 staged) applications', app_fixture: 'container_play_2.1_staged' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.2 dist applications', app_fixture: 'container_play_2.2_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.2 staged applications', app_fixture: 'container_play_2.2_staged' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a Ratpack application', app_fixture: 'container_ratpack_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a Spring Boot application', app_fixture: 'container_spring_boot_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a distZip application', app_fixture: 'container_dist_zip' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end end diff --git a/spec/java_buildpack/util/play/pre22_staged_spec.rb b/spec/java_buildpack/util/play/pre22_staged_spec.rb index fcfc54898a..3d92435a54 100644 --- a/spec/java_buildpack/util/play/pre22_staged_spec.rb +++ b/spec/java_buildpack/util/play/pre22_staged_spec.rb @@ -27,55 +27,55 @@ let(:trigger) { described_class.new(droplet).supports? } it 'does not recognize non-applications' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.0 dist applications', app_fixture: 'container_play_2.0_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.1 dist applications', app_fixture: 'container_play_2.1_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'recognizes Play 2.1 staged (or equivalently 2.0 staged) applications', app_fixture: 'container_play_2.1_staged' do - expect(trigger).to be + expect(trigger).to be_truthy end it 'does not recognize Play 2.2 dist applications', app_fixture: 'container_play_2.2_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize Play 2.2 staged applications', app_fixture: 'container_play_2.2_staged' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a Ratpack application', app_fixture: 'container_ratpack_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a Spring Boot application', app_fixture: 'container_spring_boot_dist' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end it 'does not recognize a distZip application', app_fixture: 'container_dist_zip' do - expect(trigger).not_to be + expect(trigger).not_to be_truthy end end diff --git a/spec/java_buildpack/util/ratpack_utils_spec.rb b/spec/java_buildpack/util/ratpack_utils_spec.rb index 65e713f57a..e631d0ca2e 100644 --- a/spec/java_buildpack/util/ratpack_utils_spec.rb +++ b/spec/java_buildpack/util/ratpack_utils_spec.rb @@ -27,19 +27,19 @@ it 'detects a dist Ratpack application', app_fixture: 'container_ratpack_dist' do - expect(utils.is?(application)).to be + expect(utils).to be_is(application) end it 'detects a staged Ratpack application', app_fixture: 'container_ratpack_staged' do - expect(utils.is?(application)).to be + expect(utils).to be_is(application) end it 'does not detect a non-Ratpack application', app_fixture: 'container_main' do - expect(utils.is?(application)).not_to be + expect(utils).not_to be_is(application) end it 'determines the version a dist Ratpack application', diff --git a/spec/java_buildpack/util/spring_boot_utils_spec.rb b/spec/java_buildpack/util/spring_boot_utils_spec.rb index 32b92ababb..77824278ea 100644 --- a/spec/java_buildpack/util/spring_boot_utils_spec.rb +++ b/spec/java_buildpack/util/spring_boot_utils_spec.rb @@ -27,31 +27,31 @@ it 'detects a dist Spring Boot application', app_fixture: 'container_spring_boot_dist' do - expect(utils.is?(application)).to be + expect(utils).to be_is(application) end it 'detects a staged Spring Boot application', app_fixture: 'container_spring_boot_staged' do - expect(utils.is?(application)).to be + expect(utils).to be_is(application) end it 'detects a JAR Spring Boot application', app_fixture: 'container_main_spring_boot_jar_launcher' do - expect(utils.is?(application)).to be + expect(utils).to be_is(application) end it 'does not detect a non-Spring Boot application', app_fixture: 'container_main' do - expect(utils.is?(application)).not_to be + expect(utils).not_to be_is(application) end it 'determines if an application is a thin application', app_fixture: 'container_main_spring_boot_thin_launcher' do - expect(utils.thin?(application)).to be + expect(utils).to be_thin(application) end it 'determines the version of a dist Spring Boot application', From bf979f6b7a1901ff968fa06a89aecba846a6f6bd Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 1 Oct 2018 16:11:09 -0700 Subject: [PATCH 447/812] Pack Java 11 in buildpack --- rakelib/dependency_cache_task.rb | 8 ++++++++ rakelib/versions_task.rb | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index bc72a5f388..9f78a97fa7 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -122,6 +122,14 @@ def configurations(component_id, configuration, sub_component_id = nil) if repository_configuration?(configuration) configuration['component_id'] = component_id configuration['sub_component_id'] = sub_component_id if sub_component_id + + if component_id == 'open_jdk_jre' && sub_component_id == 'jre' + c1 = configuration.clone + c1['version'] = '11.+' + + configurations << c1 + end + configurations << configuration else configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 15d4a0190f..4843f51adf 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -70,6 +70,7 @@ def initialize 'jacoco_agent' => 'JaCoCo Agent', 'jprofiler_profiler' => 'JProfiler Profiler', 'jre' => 'OpenJDK JRE', + 'jre-11' => 'OpenJDK JRE 11', 'jrebel_agent' => 'JRebel Agent', 'jvmkill_agent' => 'jvmkill Agent', 'lifecycle_support' => 'Tomcat Lifecycle Support', @@ -153,6 +154,15 @@ def configurations(component_id, configuration, sub_component_id = nil) if repository_configuration?(configuration) configuration['component_id'] = component_id configuration['sub_component_id'] = sub_component_id if sub_component_id + + if component_id == 'open_jdk_jre' && sub_component_id == 'jre' + c1 = configuration.clone + c1['sub_component_id'] = 'jre-11' + c1['version'] = '11.+' + + configurations << c1 + end + configurations << configuration else configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } From 41b8ff85665cdb0bbfb956d138946b582ef53711 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 1 Oct 2018 16:13:02 -0700 Subject: [PATCH 448/812] Polishing --- config/dynatrace_appmon_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/dynatrace_appmon_agent.yml b/config/dynatrace_appmon_agent.yml index 5012feb6c6..7e9d57aa13 100644 --- a/config/dynatrace_appmon_agent.yml +++ b/config/dynatrace_appmon_agent.yml @@ -17,4 +17,4 @@ --- version: 7.1.0_+ repository_root: https://files.dynatrace.com/downloads/appmon/cloudfoundry/buildpack/java -default_agent_name: +default_agent_name: From 136412a291af27877a09ba5e5365a59a9c5dfce9 Mon Sep 17 00:00:00 2001 From: Rene Schuenemann Date: Thu, 27 Sep 2018 11:31:25 +0200 Subject: [PATCH 449/812] SAP Machine Update This change updates the SAP Machine configuration to download version 11. [resolves #641] --- config/sap_machine_jre.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/sap_machine_jre.yml b/config/sap_machine_jre.yml index b76c74944c..8257ec0234 100644 --- a/config/sap_machine_jre.yml +++ b/config/sap_machine_jre.yml @@ -17,8 +17,8 @@ # Configuration for JRE repository --- jre: - version: 10.+ - repository_root: "https://sap.github.io/SapMachine/assets/cf/jre/10/linux/x86_64" + version: 11.+ + repository_root: "https://sap.github.io/SapMachine/assets/cf/jre/11/linux/x86_64" jvmkill_agent: version: 1.+ repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" From 809536461574d7f2280ef66814ce8801ef569af0 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 8 Oct 2018 09:09:04 -0700 Subject: [PATCH 450/812] Azure Application Insights Agent This change adds support for the Azure Application Insights Agent. [resolves #620] --- config/azure_application_insights_agent.yml | 19 +++++ config/components.yml | 1 + config/sky_walking_agent.yml | 4 +- .../azure_application_insights_agent.rb | 59 ++++++++++++++ rakelib/versions_task.rb | 79 ++++++++++--------- .../AI-Agent.xml | 25 ++++++ .../stub-azure-application-insights-agent.jar | 0 .../azure_application_insights_agent_spec.rb | 73 +++++++++++++++++ 8 files changed, 218 insertions(+), 42 deletions(-) create mode 100644 config/azure_application_insights_agent.yml create mode 100644 lib/java_buildpack/framework/azure_application_insights_agent.rb create mode 100644 resources/azure_application_insights_agent/AI-Agent.xml create mode 100644 spec/fixtures/stub-azure-application-insights-agent.jar create mode 100644 spec/java_buildpack/framework/azure_application_insights_agent_spec.rb diff --git a/config/azure_application_insights_agent.yml b/config/azure_application_insights_agent.yml new file mode 100644 index 0000000000..71478411dd --- /dev/null +++ b/config/azure_application_insights_agent.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Azure Application Insights framework. +--- +version: 2.+ +repository_root: https://java-buildpack.cloudfoundry.org/azure-application-insights diff --git a/config/components.yml b/config/components.yml index fea4f5b43e..1863871b04 100644 --- a/config/components.yml +++ b/config/components.yml @@ -42,6 +42,7 @@ frameworks: - "JavaBuildpack::Framework::MultiBuildpack" - "JavaBuildpack::Framework::AppDynamicsAgent" - "JavaBuildpack::Framework::AspectjWeaverAgent" + - "JavaBuildpack::Framework::AzureApplicationInsightsAgent" - "JavaBuildpack::Framework::ClientCertificateMapper" - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::ContainerSecurityProvider" diff --git a/config/sky_walking_agent.yml b/config/sky_walking_agent.yml index b85bfce02a..af501435da 100644 --- a/config/sky_walking_agent.yml +++ b/config/sky_walking_agent.yml @@ -13,9 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Configuration for the Spring Auto Reconfiguration framework. -# Note that the repository is shared with the Play Auto Reconfiguration framework and should be kept in step to -# avoid conflicts. +# Configuration for the Sky Walking framework. --- version: 3.+ repository_root: https://java-buildpack.cloudfoundry.org/sky-walking diff --git a/lib/java_buildpack/framework/azure_application_insights_agent.rb b/lib/java_buildpack/framework/azure_application_insights_agent.rb new file mode 100644 index 0000000000..69351502d4 --- /dev/null +++ b/lib/java_buildpack/framework/azure_application_insights_agent.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling Azure Application Insights support. + class AzureApplicationInsightsAgent < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + @droplet.copy_resources + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + credentials = @application.services.find_service(FILTER, INSTRUMENTATION_KEY)['credentials'] + + @droplet + .java_opts.add_javaagent(@droplet.sandbox + jar_name) + .add_system_property('APPLICATION_INSIGHTS_IKEY', credentials[INSTRUMENTATION_KEY]) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, INSTRUMENTATION_KEY + end + + FILTER = /azure-application-insights/ + + INSTRUMENTATION_KEY = 'instrumentation_key' + + private_constant :FILTER, :INSTRUMENTATION_KEY + + end + + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 4843f51adf..9cc89e2ec8 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -51,45 +51,46 @@ def initialize DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/ NAME_MAPPINGS = { - 'access_logging_support' => 'Tomcat Access Logging Support', - 'agent' => 'Java Memory Assistant Agent', - 'app_dynamics_agent' => 'AppDynamics Agent', - 'clean_up' => 'Java Memory Assistant Clean Up', - 'client_certificate_mapper' => 'Client Certificate Mapper', - 'container_customizer' => 'Spring Boot Container Customizer', - 'container_security_provider' => 'Container Security Provider', - 'contrast_security_agent' => 'Contrast Security Agent', - 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', - 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', - 'dynatrace_one_agent' => 'Dynatrace OneAgent', - 'geode_store' => 'Geode Tomcat Session Store', - 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', - 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', - 'groovy' => 'Groovy', - 'introscope_agent' => 'CA Introscope APM Framework', - 'jacoco_agent' => 'JaCoCo Agent', - 'jprofiler_profiler' => 'JProfiler Profiler', - 'jre' => 'OpenJDK JRE', - 'jre-11' => 'OpenJDK JRE 11', - 'jrebel_agent' => 'JRebel Agent', - 'jvmkill_agent' => 'jvmkill Agent', - 'lifecycle_support' => 'Tomcat Lifecycle Support', - 'logging_support' => 'Tomcat Logging Support', - 'luna_security_provider' => 'Gemalto Luna Security Provider', - 'maria_db_jdbc' => 'MariaDB JDBC Driver', - 'memory_calculator' => 'Memory Calculator', - 'metric_writer' => 'Metric Writer', - 'new_relic_agent' => 'New Relic Agent', - 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', - 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', - 'redis_store' => 'Redis Session Store', - 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', - 'sky_walking_agent' => 'SkyWalking', - 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', - 'spring_boot_cli' => 'Spring Boot CLI', - 'takipi_agent' => 'Takipi Agent', - 'tomcat' => 'Tomcat', - 'your_kit_profiler' => 'YourKit Profiler' + 'access_logging_support' => 'Tomcat Access Logging Support', + 'agent' => 'Java Memory Assistant Agent', + 'app_dynamics_agent' => 'AppDynamics Agent', + 'azure_application_insights_agent' => 'Azure Application Insights Agent', + 'clean_up' => 'Java Memory Assistant Clean Up', + 'client_certificate_mapper' => 'Client Certificate Mapper', + 'container_customizer' => 'Spring Boot Container Customizer', + 'container_security_provider' => 'Container Security Provider', + 'contrast_security_agent' => 'Contrast Security Agent', + 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', + 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', + 'dynatrace_one_agent' => 'Dynatrace OneAgent', + 'geode_store' => 'Geode Tomcat Session Store', + 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', + 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', + 'groovy' => 'Groovy', + 'introscope_agent' => 'CA Introscope APM Framework', + 'jacoco_agent' => 'JaCoCo Agent', + 'jprofiler_profiler' => 'JProfiler Profiler', + 'jre' => 'OpenJDK JRE', + 'jre-11' => 'OpenJDK JRE 11', + 'jrebel_agent' => 'JRebel Agent', + 'jvmkill_agent' => 'jvmkill Agent', + 'lifecycle_support' => 'Tomcat Lifecycle Support', + 'logging_support' => 'Tomcat Logging Support', + 'luna_security_provider' => 'Gemalto Luna Security Provider', + 'maria_db_jdbc' => 'MariaDB JDBC Driver', + 'memory_calculator' => 'Memory Calculator', + 'metric_writer' => 'Metric Writer', + 'new_relic_agent' => 'New Relic Agent', + 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', + 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', + 'redis_store' => 'Redis Session Store', + 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', + 'sky_walking_agent' => 'SkyWalking', + 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', + 'spring_boot_cli' => 'Spring Boot CLI', + 'takipi_agent' => 'Takipi Agent', + 'tomcat' => 'Tomcat', + 'your_kit_profiler' => 'YourKit Profiler' }.freeze PLATFORM_PATTERN = /\{platform\}/ diff --git a/resources/azure_application_insights_agent/AI-Agent.xml b/resources/azure_application_insights_agent/AI-Agent.xml new file mode 100644 index 0000000000..e508e3e087 --- /dev/null +++ b/resources/azure_application_insights_agent/AI-Agent.xml @@ -0,0 +1,25 @@ + + + + + + + + 1000 + + + \ No newline at end of file diff --git a/spec/fixtures/stub-azure-application-insights-agent.jar b/spec/fixtures/stub-azure-application-insights-agent.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb b/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb new file mode 100644 index 0000000000..32538942db --- /dev/null +++ b/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/azure_application_insights_agent' + +describe JavaBuildpack::Framework::AzureApplicationInsightsAgent do + include_context 'with component help' + + let(:configuration) do + { 'default_application_name' => nil } + end + + it 'does not detect without azure-application-insights service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?).with(/azure-application-insights/, 'instrumentation_key') + .and_return(true) + end + + it 'detects with azure-application-insights service' do + expect(component.detect).to eq("azure-application-insights-agent=#{version}") + end + + it 'downloads Azure Application Insights agent JAR', + cache_fixture: 'stub-azure-application-insights-agent.jar' do + + component.compile + + expect(sandbox + "azure_application_insights_agent-#{version}.jar").to exist + end + + it 'copies resources', + cache_fixture: 'stub-azure-application-insights-agent.jar' do + + component.compile + + expect(sandbox + 'AI-Agent.xml').to exist + end + + it 'updates JAVA_OPTS' do + allow(services).to receive(:find_service) + .and_return('credentials' => { 'instrumentation_key' => 'test-instrumentation-key' }) + + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/azure_application_insights_agent/' \ + "azure_application_insights_agent-#{version}.jar") + expect(java_opts).to include('-DAPPLICATION_INSIGHTS_IKEY=test-instrumentation-key') + end + + end + +end From f8b03ca65d68f7c70ba6f45975640efd96d6dd29 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 23 Oct 2018 14:13:24 -0700 Subject: [PATCH 451/812] Javaagent Configuration Example This change updates the documentation to provide an example of how to configure an included javaagent using JAVA_OPTS. [resolves #555] --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index b52f90f76e..c2da21279d 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,12 @@ If the key or value contains an environment variable that you want to bind at ru $ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{ arguments: "-server.port=\$PORT -foo=bar" }' ``` +An example of configuration is to specify a `javaagent` that is packaged within an application. + +```bash +$ cf set-env my-application JAVA_OPTS '-javaagent:app/META-INF/myagent.jar -Dmyagent.config_file=app/META-INF/my_agent.conf' +``` + Environment variable can also be specified in the applications `manifest` file. For example, to specify an environment variable in an applications manifest file that disables Auto-reconfiguration. ```bash From c4c06f8cc29033434a8bcd133d2eccfabd82f888 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 23 Oct 2018 15:43:43 -0700 Subject: [PATCH 452/812] Security Provider Classpath Previously, an attempt to ensure that the security providers showed in the new Java 9+ classpath (not in an ext directory) did not work. Instead, they were randomly spread among various classpaths depending on which container was being used. This change introduces a root_libraries abstraction that identifies dependencies that MUST be in the SYSTEM classloader, and then updates all of the containers to ensure that they are. [resolves #585] --- lib/java_buildpack/buildpack.rb | 7 +- .../component/additional_libraries.rb | 2 +- lib/java_buildpack/component/droplet.rb | 10 ++- .../component/root_libraries.rb | 57 +++++++++++++++ lib/java_buildpack/container/dist_zip_like.rb | 8 +-- lib/java_buildpack/container/groovy.rb | 6 +- lib/java_buildpack/container/java_main.rb | 6 +- .../container/spring_boot_cli.rb | 6 +- lib/java_buildpack/container/tomcat.rb | 4 +- .../tomcat/tomcat_logging_support.rb | 16 +---- .../container/tomcat/tomcat_setenv.rb | 66 ++++++++++++++++++ .../framework/container_security_provider.rb | 4 +- .../framework/dyadic_ekm_security_provider.rb | 4 +- .../framework/luna_security_provider.rb | 4 +- spec/droplet_helper.rb | 11 ++- spec/fixtures/root_libs/test-jar-3.jar | Bin 0 -> 342 bytes spec/fixtures/root_libs/test-jar-4.jar | Bin 0 -> 342 bytes .../container/dist_zip_like_spec.rb | 6 +- spec/java_buildpack/container/groovy_spec.rb | 6 +- .../container/java_main_spec.rb | 18 +++-- spec/java_buildpack/container/ratpack_spec.rb | 3 +- .../container/spring_boot_cli_spec.rb | 3 +- .../container/spring_boot_spec.rb | 3 +- .../tomcat/tomcat_logging_support_spec.rb | 9 +-- .../container/tomcat/tomcat_setenv_spec.rb | 42 +++++++++++ spec/java_buildpack/container/tomcat_spec.rb | 1 + .../container_security_provider_spec.rb | 4 +- .../dyadic_ekm_security_provider_spec.rb | 4 +- .../framework/luna_security_provider_spec.rb | 12 ++-- 29 files changed, 256 insertions(+), 66 deletions(-) create mode 100644 lib/java_buildpack/component/root_libraries.rb create mode 100644 lib/java_buildpack/container/tomcat/tomcat_setenv.rb create mode 100644 spec/fixtures/root_libs/test-jar-3.jar create mode 100644 spec/fixtures/root_libs/test-jar-4.jar create mode 100644 spec/java_buildpack/container/tomcat/tomcat_setenv_spec.rb diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 2dc7b65251..03b8d29d40 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -26,6 +26,7 @@ require 'java_buildpack/component/java_opts' require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/component/networking' +require 'java_buildpack/component/root_libraries' require 'java_buildpack/component/security_providers' require 'java_buildpack/logging/logger_factory' require 'java_buildpack/util/cache/application_cache' @@ -135,6 +136,7 @@ def initialize(app_dir, application) 'extension_directories' => Component::ExtensionDirectories.new(app_dir), 'java_opts' => @java_opts, 'networking' => Component::Networking.new, + 'root_libraries' => Component::RootLibraries.new(app_dir), 'security_providers' => Component::SecurityProviders.new } @@ -185,8 +187,9 @@ def instantiate(components, java_home, component_info) configuration: Util::ConfigurationUtils.load(component_id), droplet: Component::Droplet.new(component_info['additional_libraries'], component_id, component_info['env_vars'], component_info['extension_directories'], - java_home, component_info['java_opts'], component_info['app_dir'], - component_info['networking'], component_info['security_providers']) + java_home, component_info['java_opts'], component_info['networking'], + component_info['app_dir'], component_info['root_libraries'], + component_info['security_providers']) } component.constantize.new(context) end diff --git a/lib/java_buildpack/component/additional_libraries.rb b/lib/java_buildpack/component/additional_libraries.rb index eac93629ad..a05e3a7afe 100644 --- a/lib/java_buildpack/component/additional_libraries.rb +++ b/lib/java_buildpack/component/additional_libraries.rb @@ -28,7 +28,7 @@ module Component class AdditionalLibraries < Array include JavaBuildpack::Util - # Creates an instance of the +JAVA_OPTS+ abstraction. + # Creates an instance of the +AdditionalLibraries+ abstraction. # # @param [Pathname] droplet_root the root directory of the droplet def initialize(droplet_root) diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index f81a2fa98d..1f3244ce80 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -67,6 +67,10 @@ class Droplet # excludes files in the sandboxes of other components attr_reader :root + # @!attribute [r] root_libraries + # @return [RootLibraries] the shared +RootLibraries+ instance for all components + attr_reader :root_libraries + # @!attribute [r] sandbox # @return [Pathname] the root of the component's sandbox attr_reader :sandbox @@ -91,9 +95,10 @@ class Droplet # @param [JavaOpts] java_opts the shared +JavaOpts+ instance for all components # @param [Networking] networking the shared +Networking+ instance for all components # @param [Pathname] root the root of the droplet + # @param [RootLibraries] root_libraries the shared +RootLibraries+ instance for all components # @param [SecurityProviders] security_providers the shared +SecurityProviders+ instance for all components - def initialize(additional_libraries, component_id, env_vars, extension_directories, java_home, java_opts, root, - networking, security_providers) + def initialize(additional_libraries, component_id, env_vars, extension_directories, java_home, java_opts, + networking, root, root_libraries, security_providers) @additional_libraries = additional_libraries @component_id = component_id @@ -117,6 +122,7 @@ def initialize(additional_libraries, component_id, env_vars, extension_directori ->(path) { !in?(path, buildpack_root) || in?(path, @sandbox) }, true ) + @root_libraries = root_libraries @networking = networking @security_providers = security_providers end diff --git a/lib/java_buildpack/component/root_libraries.rb b/lib/java_buildpack/component/root_libraries.rb new file mode 100644 index 0000000000..8cef844931 --- /dev/null +++ b/lib/java_buildpack/component/root_libraries.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/component' +require 'java_buildpack/util/qualify_path' + +module JavaBuildpack + module Component + + # An abstraction around the root libraries provided to a droplet by components. + # + # A new instance of this type should be created once for the application. + class RootLibraries < Array + include JavaBuildpack::Util + + # Creates an instance of the +RootLibraries+ abstraction. + # + # @param [Pathname] droplet_root the root directory of the droplet + def initialize(droplet_root) + @droplet_root = droplet_root + end + + # Returns the collection as a collection of paths qualified to the +droplet_root+. + # + # @return [Array] the contents of the collection as paths qualified to +droplet_root+ + def qualified_paths + sort.map { |path| qualify_path path } + end + + # Symlink the contents of the collection to a destination directory. + # + # @param [Pathname] destination the destination to link to + # @return [Void] + def link_to(destination) + FileUtils.mkdir_p destination + each { |path| (destination + path.basename).make_symlink(path.relative_path_from(destination)) } + end + + end + + end +end diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 9e4687344f..86ce620f66 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -83,8 +83,8 @@ def supports? private_constant :PATTERN_APP_CLASSPATH, :PATTERN_CLASSPATH def augment_app_classpath(content) - additional_classpath = @droplet.additional_libraries.sort.map do |additional_library| - "$app_home/#{additional_library.relative_path_from(start_script(root).dirname)}" + additional_classpath = (@droplet.additional_libraries + @droplet.root_libraries).sort.map do |library| + "$app_home/#{library.relative_path_from(start_script(root).dirname)}" end update_file start_script(root), content, @@ -92,8 +92,8 @@ def augment_app_classpath(content) end def augment_classpath(content) - additional_classpath = @droplet.additional_libraries.sort.map do |additional_library| - "$APP_HOME/#{additional_library.relative_path_from(root)}" + additional_classpath = (@droplet.additional_libraries + @droplet.root_libraries).sort.map do |library| + "$APP_HOME/#{library.relative_path_from(root)}" end update_file start_script(root), content, diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index d50a6d8924..417f0643ac 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -59,7 +59,7 @@ def release @droplet.java_home.as_env_var, 'exec', qualify_path(@droplet.sandbox + 'bin/groovy', @droplet.root), - @droplet.additional_libraries.as_classpath, + classpath, relative_main_groovy, relative_other_groovy ].flatten.compact.join(' ') @@ -79,6 +79,10 @@ def add_libs (@droplet.root + '**/*.jar').glob.each { |jar| @droplet.additional_libraries << jar } end + def classpath + ([@droplet.additional_libraries.as_classpath] + @droplet.root_libraries.qualified_paths).join(':') + end + def main_groovy candidates = JavaBuildpack::Util::GroovyUtils.groovy_files(@application) diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index b1d8df8648..6170bcfa1b 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -73,7 +73,6 @@ def release @droplet.additional_libraries.insert 0, @application.root end - classpath = @spring_boot_utils.is?(@application) ? '-cp $PWD/.' : @droplet.additional_libraries.as_classpath release_text(classpath) end @@ -102,6 +101,11 @@ def arguments @configuration[ARGUMENTS_PROPERTY] end + def classpath + cp = @spring_boot_utils.is?(@application) ? '-cp $PWD/.' : @droplet.additional_libraries.as_classpath + ([cp] + @droplet.root_libraries.qualified_paths).join(':') + end + def main_class JavaBuildpack::Util::JavaMainUtils.main_class(@application, @configuration) end diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index c33bb09e92..7f9132d6b9 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -56,7 +56,7 @@ def release 'exec', qualify_path(@droplet.sandbox + 'bin/spring', @droplet.root), 'run', - @droplet.additional_libraries.as_classpath, + classpath, relative_groovy_files ].flatten.compact.join(' ') end @@ -71,6 +71,10 @@ def supports? private + def classpath + ([@droplet.additional_libraries.as_classpath] + @droplet.root_libraries.qualified_paths).join(':') + end + def relative_groovy_files JavaBuildpack::Util::GroovyUtils.groovy_files(@application).map do |gf| gf.relative_path_from(@application.root) diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index c64dbb1daf..9557a5ef5a 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -25,6 +25,7 @@ require 'java_buildpack/container/tomcat/tomcat_lifecycle_support' require 'java_buildpack/container/tomcat/tomcat_logging_support' require 'java_buildpack/container/tomcat/tomcat_redis_store' +require 'java_buildpack/container/tomcat/tomcat_setenv' require 'java_buildpack/util/java_main_utils' module JavaBuildpack @@ -55,10 +56,11 @@ def sub_components(context) TomcatInstance.new(sub_configuration_context(context, 'tomcat')), TomcatAccessLoggingSupport.new(sub_configuration_context(context, 'access_logging_support')), TomcatGeodeStore.new(sub_configuration_context(context, 'geode_store')), + TomcatInsightSupport.new(context), TomcatLifecycleSupport.new(sub_configuration_context(context, 'lifecycle_support')), TomcatLoggingSupport.new(sub_configuration_context(context, 'logging_support')), TomcatRedisStore.new(sub_configuration_context(context, 'redis_store')), - TomcatInsightSupport.new(context) + TomcatSetenv.new(context) ] tomcat_configuration = @configuration['tomcat'] diff --git a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb index d39191f7fd..390fddb518 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb @@ -26,7 +26,7 @@ class TomcatLoggingSupport < JavaBuildpack::Component::VersionedDependencyCompon # (see JavaBuildpack::Component::BaseComponent#compile) def compile download_jar(jar_name, bin) - write_set_env + @droplet.root_libraries << (bin + jar_name) end # (see JavaBuildpack::Component::BaseComponent#release) @@ -49,20 +49,6 @@ def jar_name "tomcat_logging_support-#{@version}.jar" end - def setenv - bin + 'setenv.sh' - end - - def write_set_env - setenv.open('w') do |f| - f.write <<~SH - #!/bin/sh - - CLASSPATH=$CLASSPATH:#{(bin + jar_name).relative_path_from(@droplet.root)} - SH - end - end - end end diff --git a/lib/java_buildpack/container/tomcat/tomcat_setenv.rb b/lib/java_buildpack/container/tomcat/tomcat_setenv.rb new file mode 100644 index 0000000000..d2bd721398 --- /dev/null +++ b/lib/java_buildpack/container/tomcat/tomcat_setenv.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' + +module JavaBuildpack + module Container + + # Encapsulates the detect, compile, and release functionality for Tomcat logging support. + class TomcatSetenv < JavaBuildpack::Component::BaseComponent + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + self.class.to_s.dash_case + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + FileUtils.mkdir_p bin + setenv.open('w') do |f| + f.write <<~SH + #!/bin/sh + + CLASSPATH=$CLASSPATH:#{@droplet.root_libraries.qualified_paths.join(':')} + SH + end + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release; end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + true + end + + private + + def bin + @droplet.sandbox + 'bin' + end + + def setenv + bin + 'setenv.sh' + end + + end + + end +end diff --git a/lib/java_buildpack/framework/container_security_provider.rb b/lib/java_buildpack/framework/container_security_provider.rb index adfca5c917..175e0fc512 100644 --- a/lib/java_buildpack/framework/container_security_provider.rb +++ b/lib/java_buildpack/framework/container_security_provider.rb @@ -28,13 +28,13 @@ class ContainerSecurityProvider < JavaBuildpack::Component::VersionedDependencyC def compile download_jar @droplet.security_providers.insert 1, 'org.cloudfoundry.security.CloudFoundryContainerProvider' - @droplet.additional_libraries << (@droplet.sandbox + jar_name) if @droplet.java_home.java_9_or_later? + @droplet.root_libraries << (@droplet.sandbox + jar_name) if @droplet.java_home.java_9_or_later? end # (see JavaBuildpack::Component::BaseComponent#release) def release if @droplet.java_home.java_9_or_later? - @droplet.additional_libraries << (@droplet.sandbox + jar_name) + @droplet.root_libraries << (@droplet.sandbox + jar_name) else @droplet.extension_directories << @droplet.sandbox end diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index f8880cf723..7d5ae0e452 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -34,7 +34,7 @@ def compile @droplet.copy_resources @droplet.security_providers << 'com.dyadicsec.provider.DYCryptoProvider' - @droplet.additional_libraries << dyadic_jar if @droplet.java_home.java_9_or_later? + @droplet.root_libraries << dyadic_jar if @droplet.java_home.java_9_or_later? credentials = @application.services.find_service(FILTER, 'ca', 'key', 'recv_timeout', 'retries', 'send_timeout', 'servers')['credentials'] @@ -47,7 +47,7 @@ def release .add_environment_variable 'LD_LIBRARY_PATH', @droplet.sandbox + 'usr/lib' if @droplet.java_home.java_9_or_later? - @droplet.additional_libraries << dyadic_jar + @droplet.root_libraries << dyadic_jar else @droplet.extension_directories << ext_dir end diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 9a25dffc9b..7a794dc319 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -34,7 +34,7 @@ def compile @droplet.copy_resources @droplet.security_providers << 'com.safenetinc.luna.provider.LunaProvider' - @droplet.additional_libraries << luna_provider_jar if @droplet.java_home.java_9_or_later? + @droplet.root_libraries << luna_provider_jar if @droplet.java_home.java_9_or_later? credentials = @application.services.find_service(FILTER, 'client', 'servers', 'groups')['credentials'] write_client credentials['client'] @@ -47,7 +47,7 @@ def release @droplet.environment_variables.add_environment_variable 'ChrystokiConfigurationPath', @droplet.sandbox if @droplet.java_home.java_9_or_later? - @droplet.additional_libraries << luna_provider_jar + @droplet.root_libraries << luna_provider_jar else @droplet.extension_directories << ext_dir end diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index fc8ac34f01..dfe1b326a1 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -43,12 +43,16 @@ let(:droplet) do JavaBuildpack::Component::Droplet.new(additional_libraries, component_id, environment_variables, - extension_directories, java_home, java_opts, app_dir, networking, - security_providers) + extension_directories, java_home, java_opts, networking, app_dir, + root_libraries, security_providers) end let(:extension_directories) { JavaBuildpack::Component::ExtensionDirectories.new app_dir } + let(:root_libraries) { JavaBuildpack::Component::RootLibraries.new app_dir } + + let(:root_libs_directory) { droplet.root + '.root_libs' } + let(:sandbox) { droplet.sandbox } let(:java_home) do @@ -86,6 +90,9 @@ extension_directories << sandbox + 'test-extension-directory-1' extension_directories << sandbox + 'test-extension-directory-2' + FileUtils.cp_r 'spec/fixtures/root_libs/.', root_libs_directory + root_libs_directory.children.each { |child| root_libraries << child } + security_providers.concat %w[test-security-provider-1 test-security-provider-2] end diff --git a/spec/fixtures/root_libs/test-jar-3.jar b/spec/fixtures/root_libs/test-jar-3.jar new file mode 100644 index 0000000000000000000000000000000000000000..8b0d26227e984fa173f2a8264b5ef31ea88debb1 GIT binary patch literal 342 zcmWIWW@Zs#;Nak32+T_JVn70%3@i-3t|5-Po_=on|4uP5Ff#;rvvYt{FhP|C;M6Pv zQ~}rQ>*(j{<{BKL=j-;__snS@Z(Y5MyxzK6=gyqp9At3C_`%a6JuhD!Pv48Bt5`TA zUPvC1mXg%U_#v*U_I!z!#dC4dC*rEp7_Mf2D*9N&2zG^l;4&o_pdGG29N^8!B*K8| u3788(okQWfZ7RZEaMe*(j{<{BKL=j-;__snS@Z(Y5MyxzK6=gyqp9At3C_`%a6JuhD!Pv48Bt5`TA zUPvC1mXg%U_#v*U_I!z!#dC4dC*rEp7_Mf2D*9N&2zG^l;4&o_pdGG29N^8!B*K8| u3788(okQWfZ7RZEaMe true, - 'ha_logging_enabled' => true, + 'logging_enabled' => true, + 'ha_logging_enabled' => true, 'tcp_keep_alive_enabled' => false } end @@ -181,8 +181,8 @@ context do let(:configuration) do { - 'logging_enabled' => true, - 'ha_logging_enabled' => true, + 'logging_enabled' => true, + 'ha_logging_enabled' => true, 'tcp_keep_alive_enabled' => true } end From 4297a526219e7adbf19378554ebde6d60c6069c7 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 25 Oct 2018 11:11:26 -0700 Subject: [PATCH 453/812] Tomcat External Configuration Offline Previously, Tomcat External Configuration was subject to the InternetAvailablity flag of the buildpack. This meant that when using an offline buildpack (as most do), external configuration could never be downloaded. Since external configuration would almost exclusively come from within the firewall, this enforcement is overkill. This change updates the implementation to download regardless of the InternetAvailablity. [resolves #638] Signed-off-by: Ben Hale --- .../container/tomcat/tomcat_external_configuration.rb | 6 +++++- .../tomcat/tomcat_external_configuration_spec.rb | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb index 41e93c5a6f..a4a6576659 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb @@ -27,7 +27,11 @@ class TomcatExternalConfiguration < JavaBuildpack::Component::VersionedDependenc # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_tar + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, 'The Tomcat External Configuration download location is always accessible' + ) do + download_tar + end end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb index 65382f96e2..3ff0eae4ee 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb @@ -17,6 +17,7 @@ require 'spec_helper' require 'component_helper' +require 'internet_availability_helper' require 'java_buildpack/container/tomcat/tomcat_external_configuration' describe JavaBuildpack::Container::TomcatExternalConfiguration do @@ -28,6 +29,16 @@ expect(component.detect).to eq("tomcat-external-configuration=#{version}") end + it 'does guarantee that internet access is available when downloading', + app_fixture: 'container_tomcat', + cache_fixture: 'stub-tomcat-external-configuration.tar.gz' do + + expect_any_instance_of(JavaBuildpack::Util::Cache::InternetAvailability) + .to receive(:available).with(true, 'The Tomcat External Configuration download location is always accessible') + + component.compile + end + it 'extracts Tomcat external configuration files from a GZipped TAR', app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat-external-configuration.tar.gz' do From 1983c36ada460c960dcba20fd576538adc1182a8 Mon Sep 17 00:00:00 2001 From: Rene Schuenemann Date: Sat, 3 Nov 2018 12:09:14 +0100 Subject: [PATCH 454/812] Update SAP Machine Repository Previously the repository containing the SAP Machine JRE was versioned such that only 11.+ could be retrieved. This change makes the repository URI general so many versions can be retrieved from it. [resolves #648] Signed-off-by: Ben Hale --- config/sap_machine_jre.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/sap_machine_jre.yml b/config/sap_machine_jre.yml index 8257ec0234..e19fe103c8 100644 --- a/config/sap_machine_jre.yml +++ b/config/sap_machine_jre.yml @@ -18,13 +18,13 @@ --- jre: version: 11.+ - repository_root: "https://sap.github.io/SapMachine/assets/cf/jre/11/linux/x86_64" + repository_root: "https://sap.github.io/SapMachine/assets/cf/jre/linux/{architecture}" jvmkill_agent: version: 1.+ repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" - class_count: - headroom: + class_count: + headroom: stack_threads: 250 From 5a2e647f0d739c3b6ed607f21d7509319965faa6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 5 Nov 2018 10:04:24 -0800 Subject: [PATCH 455/812] Polishing Signed-off-by: Ben Hale --- config/sap_machine_jre.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/sap_machine_jre.yml b/config/sap_machine_jre.yml index e19fe103c8..a69a06032a 100644 --- a/config/sap_machine_jre.yml +++ b/config/sap_machine_jre.yml @@ -25,6 +25,6 @@ jvmkill_agent: memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" - class_count: - headroom: + class_count: + headroom: stack_threads: 250 From 38af8e41567343ccbae92cab9b610fd9703dff40 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 15 Nov 2018 09:49:05 -0800 Subject: [PATCH 456/812] Set Active Processor Count Currently, only Java 10 and later can automatically determine processor count inside of a container. Previous versions always return a single processor which can cause performance issues. This change sets the -XX:ActiveProcessorCount=$(nproc) JAVA_OPTS for all versions of the JVM before Java 10. [resolves #650] Signed-off-by: Ben Hale --- .../component/immutable_java_home.rb | 7 +++++++ .../component/mutable_java_home.rb | 10 +++++++++- lib/java_buildpack/jre/open_jdk_like_jre.rb | 6 ++++++ .../jre/open_jdk_like_jre_spec.rb | 19 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index 41a5160bf1..fb501b99de 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -57,6 +57,13 @@ def java_9_or_later? @delegate.java_9_or_later? end + # Whether or not the version of Java is 10 or later + # + # @return [Boolean] +true+ iff the version is 10.0.0 or later + def java_10_or_later? + @delegate.java_10_or_later? + end + # @return [Pathname] the root of the droplet's +JAVA_HOME+ def root @delegate.root diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index d03f2635c1..286f2daa1e 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -47,11 +47,19 @@ def java_9_or_later? @version >= VERSION_9 end + # Whether or not the version of Java is 10 or later + # @return [Boolean] +true+ if and only if the version is 10.0.0 or later + def java_10_or_later? + @version >= VERSION_10 + end + VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0').freeze VERSION_9 = JavaBuildpack::Util::TokenizedVersion.new('9.0.0').freeze - private_constant :VERSION_8, :VERSION_9 + VERSION_10 = JavaBuildpack::Util::TokenizedVersion.new('10.0.0').freeze + + private_constant :VERSION_8, :VERSION_9, :VERSION_10 end diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index edf1ba9f1f..8602eea9e1 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -65,6 +65,8 @@ def release @droplet .java_opts .add_system_property('java.io.tmpdir', '$TMPDIR') + + set_active_processor_count unless @droplet.java_home.java_10_or_later? end private @@ -86,6 +88,10 @@ def link_local_dns? end end + def set_active_processor_count + @droplet.java_opts.add_option '-XX:ActiveProcessorCount', '$(nproc)' + end + end end diff --git a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index b035bde48c..ddec80e3ec 100644 --- a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -19,6 +19,7 @@ require 'component_helper' require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/jre/open_jdk_like_jre' +require 'java_buildpack/util/tokenized_version' require 'resolv' describe JavaBuildpack::Jre::OpenJDKLikeJre do @@ -74,4 +75,22 @@ expect(networking.networkaddress_cache_negative_ttl).to eq 0 end + it 'sets active processor count before Java 10', + cache_fixture: 'stub-java.tar.gz' do + + java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_162') + + component.release + + expect(java_opts).to include('-XX:ActiveProcessorCount=$(nproc)') + end + + it 'does not set active processor count from Java 10 and later', + cache_fixture: 'stub-java.tar.gz' do + + java_home.version = JavaBuildpack::Util::TokenizedVersion.new('10.0.1_10') + + expect(java_opts).not_to include('-XX:ActiveProcessorCount=$(nproc)') + end + end From f362bd6d79bb3dfc4689e0c80850f04f9499ec4e Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 15 Nov 2018 14:10:39 -0800 Subject: [PATCH 457/812] Documentation Update This change updates the documentation for AppDynamics as it was out of date and didn't properly list the directory that a file should be placed in. [resolves #652] Signed-off-by: Ben Hale --- docs/framework-app_dynamics_agent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 2803ee83fb..c9a30f3ba5 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -42,7 +42,7 @@ The framework can be configured by modifying the [`config/app_dynamics_agent.yml | `version` | The version of AppDynamics to use. Candidate versions can be found in [this listing][]. ### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/app_dynamics_agent` directory in the buildpack fork. For example, to override the default `app-agent-config.xml` add your custom file to `resources/app_dynamics_agent/conf/app-agent-config.xml`. +The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/app_dynamics_agent` directory in the buildpack fork. For example, to override the default `app-agent-config.xml` add your custom file to `resources/app_dynamics_agent/conf/app-agent-config.xml`. [`config/app_dynamics_agent.yml`]: ../config/app_dynamics_agent.yml [AppDynamics Java Agent Configuration Properties]: https://docs.appdynamics.com/display/PRO42/Java+Agent+Configuration+Properties From dcf5280db3d623cab6737a97cef81eaef3f472a6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 26 Nov 2018 12:10:24 -0800 Subject: [PATCH 458/812] Set Processor Count This change continues an earlier change and instead of conditionally setting the processor count on Java 9 and earlier, sets it at all times since the algorithm used to due the calculation is fundamentally flawed. [resolves #650] Signed-off-by: Ben Hale --- lib/java_buildpack/jre/open_jdk_like_jre.rb | 7 +------ spec/java_buildpack/jre/open_jdk_like_jre_spec.rb | 12 +----------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index 8602eea9e1..e42e8cc613 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -64,9 +64,8 @@ def compile def release @droplet .java_opts + .add_option('-XX:ActiveProcessorCount', '$(nproc)') .add_system_property('java.io.tmpdir', '$TMPDIR') - - set_active_processor_count unless @droplet.java_home.java_10_or_later? end private @@ -88,10 +87,6 @@ def link_local_dns? end end - def set_active_processor_count - @droplet.java_opts.add_option '-XX:ActiveProcessorCount', '$(nproc)' - end - end end diff --git a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb index ddec80e3ec..1d2cbe1af3 100644 --- a/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_jre_spec.rb @@ -75,22 +75,12 @@ expect(networking.networkaddress_cache_negative_ttl).to eq 0 end - it 'sets active processor count before Java 10', + it 'sets active processor count', cache_fixture: 'stub-java.tar.gz' do - java_home.version = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_162') - component.release expect(java_opts).to include('-XX:ActiveProcessorCount=$(nproc)') end - it 'does not set active processor count from Java 10 and later', - cache_fixture: 'stub-java.tar.gz' do - - java_home.version = JavaBuildpack::Util::TokenizedVersion.new('10.0.1_10') - - expect(java_opts).not_to include('-XX:ActiveProcessorCount=$(nproc)') - end - end From 8fbdf81ea7ef111b6a164ec04737005e60db49aa Mon Sep 17 00:00:00 2001 From: Glenn Oppegard Date: Thu, 3 Jan 2019 16:41:39 -0700 Subject: [PATCH 459/812] Headroom Example Option This change provides an example for the `headroom` memory configuration option. Signed-off-by: Brandon Stokes Signed-off-by: Ben Hale --- docs/jre-open_jdk_jre.md | 4 ++++ docs/jre-oracle_jre.md | 4 ++++ docs/jre-sap_machine_jre.md | 4 ++++ docs/jre-zulu_jre.md | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 0cc5c6867a..3073c3d4e5 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -104,6 +104,10 @@ class_count: 500 A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. +```yaml +headroom: 10 +``` + #### Stack Threads The amount of memory that should be allocated to stacks is given as an amount of memory per diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 4062f38461..d408384d3c 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -120,6 +120,10 @@ class_count: 500 A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. +```yaml +headroom: 10 +``` + #### Stack Threads The amount of memory that should be allocated to stacks is given as an amount of memory per diff --git a/docs/jre-sap_machine_jre.md b/docs/jre-sap_machine_jre.md index 9e1d4ad057..c7d171f2d4 100644 --- a/docs/jre-sap_machine_jre.md +++ b/docs/jre-sap_machine_jre.md @@ -107,6 +107,10 @@ class_count: 500 A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. +```yaml +headroom: 10 +``` + #### Stack Threads The amount of memory that should be allocated to stacks is given as an amount of memory per diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index d21ceeb5bd..2f1b601a96 100644 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -111,6 +111,10 @@ class_count: 500 A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. +```yaml +headroom: 10 +``` + #### Stack Threads The amount of memory that should be allocated to stacks is given as an amount of memory per From 883818dd9dc58fd36b400f09833d562970201060 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Jan 2019 12:38:05 -0800 Subject: [PATCH 460/812] Polishing Signed-off-by: Ben Hale --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c2da21279d..1074164aa8 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ $ cf set-env my-application JBP_CONFIG_REPOSITORY '{ default_repository_root: "h If the key or value contains an environment variable that you want to bind at runtime you need to escape it from your shell. For example, to add command line arguments containing an environment variable to a [Java Main](docs/container-java_main.md) application. ```bash -$ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{ arguments: "-server.port=\$PORT -foo=bar" }' +$ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{ arguments: "--server.port=9090 --foo=bar" }' ``` An example of configuration is to specify a `javaagent` that is packaged within an application. From 21469f373b29d7085b8c14b1184e7ca2bcfff571 Mon Sep 17 00:00:00 2001 From: Rob Hardt Date: Fri, 29 Dec 2017 16:40:16 -0800 Subject: [PATCH 461/812] Fix multi-buildpack /bin /lib and backwards compatibility https://github.com/cloudfoundry/java-buildpack/issues/535 - Add logic to handle situations when there are multiple /deps directories - Fix the assumptions in the unit tests around where the deps dirs are located - Modified the rspec fixture to reflect deps dirs [#536] Signed-off-by: Ben Hale --- .../framework/multi_buildpack.rb | 14 ++++--- .../0/{ => 0}/bin/.gitkeep | 0 .../0/0/config.yml | 3 ++ .../0/{ => 0}/lib/.gitkeep | 0 .../{ => 0}/1/.gitkeep | 0 .../{ => 0}/2/config.yml | 2 +- .../0/config.yml | 3 -- .../1/0/bin/.gitkeep | 0 .../1/0/config.yml | 3 ++ .../1/0/lib/.gitkeep | 0 .../1/1/.gitkeep | 0 .../1/2/config.yml | 41 ++++++++++++++++++ .../2/0/bin/.gitkeep | 0 .../2/0/config.yml | 3 ++ .../2/0/lib/.gitkeep | 0 .../2/1/.gitkeep | 0 .../2/2/config.yml | 41 ++++++++++++++++++ .../framework/multi_buildpack_spec.rb | 42 +++++++++++++++---- 18 files changed, 136 insertions(+), 16 deletions(-) rename spec/fixtures/framework_multi_buildpack_deps/0/{ => 0}/bin/.gitkeep (100%) create mode 100644 spec/fixtures/framework_multi_buildpack_deps/0/0/config.yml rename spec/fixtures/framework_multi_buildpack_deps/0/{ => 0}/lib/.gitkeep (100%) rename spec/fixtures/framework_multi_buildpack_deps/{ => 0}/1/.gitkeep (100%) rename spec/fixtures/framework_multi_buildpack_deps/{ => 0}/2/config.yml (97%) delete mode 100644 spec/fixtures/framework_multi_buildpack_deps/0/config.yml create mode 100644 spec/fixtures/framework_multi_buildpack_deps/1/0/bin/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/1/0/config.yml create mode 100644 spec/fixtures/framework_multi_buildpack_deps/1/0/lib/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/1/1/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/1/2/config.yml create mode 100644 spec/fixtures/framework_multi_buildpack_deps/2/0/bin/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/2/0/config.yml create mode 100644 spec/fixtures/framework_multi_buildpack_deps/2/0/lib/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/2/1/.gitkeep create mode 100644 spec/fixtures/framework_multi_buildpack_deps/2/2/config.yml diff --git a/lib/java_buildpack/framework/multi_buildpack.rb b/lib/java_buildpack/framework/multi_buildpack.rb index a7982d2932..80ffbc03f5 100644 --- a/lib/java_buildpack/framework/multi_buildpack.rb +++ b/lib/java_buildpack/framework/multi_buildpack.rb @@ -20,7 +20,6 @@ require 'java_buildpack/component/base_component' require 'java_buildpack/framework' require 'java_buildpack/logging/logger_factory' -require 'java_buildpack/util/qualify_path' require 'yaml' module JavaBuildpack @@ -123,11 +122,16 @@ def add_bin(dep_directory) return unless bin_directory.exist? @droplet.environment_variables - .add_environment_variable('PATH', "$PATH:#{qualify_path(bin_directory, @droplet.root)}") + .add_environment_variable('PATH', "$PATH:#{qualify_dep(bin_directory)}") '$PATH' end + def qualify_dep(dep_dir) + ret = dep_dir.to_s.gsub(/.+(\/deps\/[0-9]+\/\w+)$/, '\1') + "$PWD/..#{ret}" + end + def add_bootclasspath_ps(java_opts) bootclasspath_ps = java_opts['bootclasspath_ps'] return unless bootclasspath_ps @@ -199,7 +203,7 @@ def add_lib(dep_directory) @droplet.environment_variables .add_environment_variable('LD_LIBRARY_PATH', - "$LD_LIBRARY_PATH:#{qualify_path(lib_directory, @droplet.root)}") + "$LD_LIBRARY_PATH:#{qualify_dep(lib_directory)}") '$LD_LIBRARY_PATH' end @@ -275,13 +279,13 @@ def contributions_message(contributions) end def dep_directories - deps = Pathname.glob('/tmp/*/deps').first + deps = Pathname.glob('/tmp/*/deps').map{|d| d.children}.flatten return [] unless deps deps - .children .select { |dep_directory| config_file(dep_directory).exist? } .sort_by(&:basename) + end def log_configuration(config) diff --git a/spec/fixtures/framework_multi_buildpack_deps/0/bin/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/0/0/bin/.gitkeep similarity index 100% rename from spec/fixtures/framework_multi_buildpack_deps/0/bin/.gitkeep rename to spec/fixtures/framework_multi_buildpack_deps/0/0/bin/.gitkeep diff --git a/spec/fixtures/framework_multi_buildpack_deps/0/0/config.yml b/spec/fixtures/framework_multi_buildpack_deps/0/0/config.yml new file mode 100644 index 0000000000..91516bd0ae --- /dev/null +++ b/spec/fixtures/framework_multi_buildpack_deps/0/0/config.yml @@ -0,0 +1,3 @@ +--- +name: test-buildpack-0-0 +config: {} diff --git a/spec/fixtures/framework_multi_buildpack_deps/0/lib/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/0/0/lib/.gitkeep similarity index 100% rename from spec/fixtures/framework_multi_buildpack_deps/0/lib/.gitkeep rename to spec/fixtures/framework_multi_buildpack_deps/0/0/lib/.gitkeep diff --git a/spec/fixtures/framework_multi_buildpack_deps/1/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/0/1/.gitkeep similarity index 100% rename from spec/fixtures/framework_multi_buildpack_deps/1/.gitkeep rename to spec/fixtures/framework_multi_buildpack_deps/0/1/.gitkeep diff --git a/spec/fixtures/framework_multi_buildpack_deps/2/config.yml b/spec/fixtures/framework_multi_buildpack_deps/0/2/config.yml similarity index 97% rename from spec/fixtures/framework_multi_buildpack_deps/2/config.yml rename to spec/fixtures/framework_multi_buildpack_deps/0/2/config.yml index 804c4a42a3..0178fd53ee 100644 --- a/spec/fixtures/framework_multi_buildpack_deps/2/config.yml +++ b/spec/fixtures/framework_multi_buildpack_deps/0/2/config.yml @@ -1,5 +1,5 @@ --- -name: test-buildpack-2 +name: test-buildpack-0-2 config: additional_libraries: - /multi-test-additional-library-1 diff --git a/spec/fixtures/framework_multi_buildpack_deps/0/config.yml b/spec/fixtures/framework_multi_buildpack_deps/0/config.yml deleted file mode 100644 index c15a4aaac4..0000000000 --- a/spec/fixtures/framework_multi_buildpack_deps/0/config.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -name: test-buildpack-0 -config: {} diff --git a/spec/fixtures/framework_multi_buildpack_deps/1/0/bin/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/1/0/bin/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/1/0/config.yml b/spec/fixtures/framework_multi_buildpack_deps/1/0/config.yml new file mode 100644 index 0000000000..b7de0f797e --- /dev/null +++ b/spec/fixtures/framework_multi_buildpack_deps/1/0/config.yml @@ -0,0 +1,3 @@ +--- +name: test-buildpack-1-0 +config: {} diff --git a/spec/fixtures/framework_multi_buildpack_deps/1/0/lib/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/1/0/lib/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/1/1/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/1/1/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/1/2/config.yml b/spec/fixtures/framework_multi_buildpack_deps/1/2/config.yml new file mode 100644 index 0000000000..4dac13df8e --- /dev/null +++ b/spec/fixtures/framework_multi_buildpack_deps/1/2/config.yml @@ -0,0 +1,41 @@ +--- +name: test-buildpack-1-2 +config: + additional_libraries: + - /multi-test-additional-library-1 + - /multi-test-additional-library-2 + environment_variables: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + extension_directories: + - /multi-test-extension-directory-1 + - /multi-test-extension-directory-2 + java_opts: + agentpaths: + - /multi-test-agent-1 + - /multi-test-agent-2 + agentpaths_with_props: + /multi-test-agent-1: + test-key-1: test-value-1 + test-key-2: test-value-2 + /multi-test-agent-2: + test-key-1: test-value-1 + test-key-2: test-value-2 + bootclasspath_ps: + - /multi-test-bootclasspath-p-1 + - /multi-test-bootclasspath-p-2 + javaagents: + - /multi-test-java-agent-1 + - /multi-test-java-agent-2 + preformatted_options: + - multi-test-preformatted-option-1 + - multi-test-preformatted-option-2 + options: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + system_properties: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + security_providers: + - multi-test-security-provider-1 + - multi-test-security-provider-2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/2/0/bin/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/2/0/bin/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/2/0/config.yml b/spec/fixtures/framework_multi_buildpack_deps/2/0/config.yml new file mode 100644 index 0000000000..8057f39eb1 --- /dev/null +++ b/spec/fixtures/framework_multi_buildpack_deps/2/0/config.yml @@ -0,0 +1,3 @@ +--- +name: test-buildpack-2-0 +config: {} diff --git a/spec/fixtures/framework_multi_buildpack_deps/2/0/lib/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/2/0/lib/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/2/1/.gitkeep b/spec/fixtures/framework_multi_buildpack_deps/2/1/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_multi_buildpack_deps/2/2/config.yml b/spec/fixtures/framework_multi_buildpack_deps/2/2/config.yml new file mode 100644 index 0000000000..89cc59bc43 --- /dev/null +++ b/spec/fixtures/framework_multi_buildpack_deps/2/2/config.yml @@ -0,0 +1,41 @@ +--- +name: test-buildpack-2-2 +config: + additional_libraries: + - /multi-test-additional-library-1 + - /multi-test-additional-library-2 + environment_variables: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + extension_directories: + - /multi-test-extension-directory-1 + - /multi-test-extension-directory-2 + java_opts: + agentpaths: + - /multi-test-agent-1 + - /multi-test-agent-2 + agentpaths_with_props: + /multi-test-agent-1: + test-key-1: test-value-1 + test-key-2: test-value-2 + /multi-test-agent-2: + test-key-1: test-value-1 + test-key-2: test-value-2 + bootclasspath_ps: + - /multi-test-bootclasspath-p-1 + - /multi-test-bootclasspath-p-2 + javaagents: + - /multi-test-java-agent-1 + - /multi-test-java-agent-2 + preformatted_options: + - multi-test-preformatted-option-1 + - multi-test-preformatted-option-2 + options: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + system_properties: + multi-test-key-1: multi-test-value-1 + multi-test-key-2: multi-test-value-2 + security_providers: + - multi-test-security-provider-1 + - multi-test-security-provider-2 diff --git a/spec/java_buildpack/framework/multi_buildpack_spec.rb b/spec/java_buildpack/framework/multi_buildpack_spec.rb index 3ce0ac9552..479138b772 100644 --- a/spec/java_buildpack/framework/multi_buildpack_spec.rb +++ b/spec/java_buildpack/framework/multi_buildpack_spec.rb @@ -23,10 +23,35 @@ describe JavaBuildpack::Framework::MultiBuildpack do include_context 'with component help' - before do - allow(Pathname).to receive(:glob).with('/tmp/*/deps').and_return([Pathname.new(app_dir)]) + let(:dep_dirs) { + tdirpath = Dir.mktmpdir + ret = Array.new + [1,2,3].each do |n| + ret.push dep_dir + end + ret + } + + def dep_dir() + ddirpath = Dir.mktmpdir+'/deps' + Dir.mkdir(ddirpath, 0755) + Pathname.new ddirpath end + before do |example| + app_fixture = example.metadata[:app_fixture] + if app_fixture + (0..2).each do |i| + if dep_dirs[i] + FileUtils.cp_r "spec/fixtures/#{app_fixture.chomp}/#{i}/.", dep_dirs[i] + end + end + end + + allow(Pathname).to receive(:glob).with('/tmp/*/deps').and_return(dep_dirs) + end + + it 'does not detect without deps' do expect(component.detect).to be_nil end @@ -34,7 +59,10 @@ it 'detects when deps with config.yml exist', app_fixture: 'framework_multi_buildpack_deps' do - expect(component.detect).to eq('multi-buildpack=test-buildpack-0,test-buildpack-2') + expect(component.detect).to include('test-buildpack-0-0', + 'test-buildpack-0-2', 'test-buildpack-1-0', + 'test-buildpack-1-2', 'test-buildpack-2-0', + 'test-buildpack-2-2') end it 'adds bin/ directory to $PATH during compile if it exists', @@ -42,7 +70,7 @@ component.compile - expect(environment_variables).to include('PATH=$PATH:$PWD/0/bin') + expect(environment_variables).to include('PATH=$PATH:$PWD/../deps/0/bin') end it 'adds bin/ directory to $PATH during release if it exists', @@ -50,7 +78,7 @@ component.release - expect(environment_variables).to include('PATH=$PATH:$PWD/0/bin') + expect(environment_variables).to include('PATH=$PATH:$PWD/../deps/0/bin') end it 'adds lib/ directory to $LD_LIBRARY_PATH during compile if it exists', @@ -58,7 +86,7 @@ component.compile - expect(environment_variables).to include('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/0/lib') + expect(environment_variables).to include('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/../deps/0/lib') end it 'adds lib/ directory to $LD_LIBRARY_PATH during release if it exists', @@ -66,7 +94,7 @@ component.release - expect(environment_variables).to include('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/0/lib') + expect(environment_variables).to include('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/../deps/0/lib') end it 'adds additional_libraries during compile', From 10f604535330883f629abf4472097c7d42409d5c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Jan 2019 13:59:12 -0800 Subject: [PATCH 462/812] Polishing [resolves #536] Signed-off-by: Ben Hale --- .idea/.rakeTasks | 2 +- .../framework/multi_buildpack.rb | 5 ++-- .../framework/multi_buildpack_spec.rb | 27 +++++++++---------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index 22d96e4075..38bd6842ba 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/lib/java_buildpack/framework/multi_buildpack.rb b/lib/java_buildpack/framework/multi_buildpack.rb index 80ffbc03f5..384336bded 100644 --- a/lib/java_buildpack/framework/multi_buildpack.rb +++ b/lib/java_buildpack/framework/multi_buildpack.rb @@ -128,7 +128,7 @@ def add_bin(dep_directory) end def qualify_dep(dep_dir) - ret = dep_dir.to_s.gsub(/.+(\/deps\/[0-9]+\/\w+)$/, '\1') + ret = dep_dir.to_s.gsub(%r{.+(/deps/[0-9]+/\w+)$}, '\1') "$PWD/..#{ret}" end @@ -279,13 +279,12 @@ def contributions_message(contributions) end def dep_directories - deps = Pathname.glob('/tmp/*/deps').map{|d| d.children}.flatten + deps = Pathname.glob('/tmp/*/deps').map(&:children).flatten return [] unless deps deps .select { |dep_directory| config_file(dep_directory).exist? } .sort_by(&:basename) - end def log_configuration(config) diff --git a/spec/java_buildpack/framework/multi_buildpack_spec.rb b/spec/java_buildpack/framework/multi_buildpack_spec.rb index 479138b772..aa3b5478c1 100644 --- a/spec/java_buildpack/framework/multi_buildpack_spec.rb +++ b/spec/java_buildpack/framework/multi_buildpack_spec.rb @@ -23,18 +23,18 @@ describe JavaBuildpack::Framework::MultiBuildpack do include_context 'with component help' - let(:dep_dirs) { - tdirpath = Dir.mktmpdir - ret = Array.new - [1,2,3].each do |n| + let(:dep_dirs) do + Dir.mktmpdir + ret = [] + [1, 2, 3].each do |_| ret.push dep_dir end ret - } + end - def dep_dir() - ddirpath = Dir.mktmpdir+'/deps' - Dir.mkdir(ddirpath, 0755) + def dep_dir + ddirpath = Dir.mktmpdir + '/deps' + Dir.mkdir(ddirpath, 0o0755) Pathname.new ddirpath end @@ -42,16 +42,13 @@ def dep_dir() app_fixture = example.metadata[:app_fixture] if app_fixture (0..2).each do |i| - if dep_dirs[i] - FileUtils.cp_r "spec/fixtures/#{app_fixture.chomp}/#{i}/.", dep_dirs[i] - end + FileUtils.cp_r "spec/fixtures/#{app_fixture.chomp}/#{i}/.", dep_dirs[i] if dep_dirs[i] end end allow(Pathname).to receive(:glob).with('/tmp/*/deps').and_return(dep_dirs) end - it 'does not detect without deps' do expect(component.detect).to be_nil end @@ -60,9 +57,9 @@ def dep_dir() app_fixture: 'framework_multi_buildpack_deps' do expect(component.detect).to include('test-buildpack-0-0', - 'test-buildpack-0-2', 'test-buildpack-1-0', - 'test-buildpack-1-2', 'test-buildpack-2-0', - 'test-buildpack-2-2') + 'test-buildpack-0-2', 'test-buildpack-1-0', + 'test-buildpack-1-2', 'test-buildpack-2-0', + 'test-buildpack-2-2') end it 'adds bin/ directory to $PATH during compile if it exists', From f180299ebb9a989649c73bd35c2a160b601024b5 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Jan 2019 14:24:31 -0800 Subject: [PATCH 463/812] New Versions of Ruby Signed-off-by: Ben Hale --- .ruby-version | 2 +- ci/docker-image/Dockerfile | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.ruby-version b/.ruby-version index 00355e29d1..59aa62c1fa 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.3.7 +2.4.5 diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 93f6097c85..05a4cb533e 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -30,10 +30,11 @@ RUN eval "$(rbenv init -)" \ && echo 'bundler' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ - && rbenv install 2.3.7 + && rbenv install 2.4.5 RUN eval "$(rbenv init -)" \ - && rbenv install 2.4.4 + && rbenv install 2.5.3 RUN eval "$(rbenv init -)" \ - && rbenv install 2.5.1 + && rbenv install 2.6.0 + From 03fc57e9d0cf64be5a53e9096c2e1d6c60d39d04 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Jan 2019 15:29:07 -0800 Subject: [PATCH 464/812] Dependency Updates Signed-off-by: Ben Hale --- .idea/codeStyles/Project.xml | 1 - .idea/misc.xml | 2 +- .idea/runConfigurations/All_Tests__2_4_.xml | 10 +- .idea/runConfigurations/All_Tests__2_5_.xml | 10 +- ...ll_Tests__2_3_.xml => All_Tests__2_6_.xml} | 12 +- .../Without_Integration_Tests__2_4_.xml | 10 +- .../Without_Integration_Tests__2_5_.xml | 10 +- ...ml => Without_Integration_Tests__2_6_.xml} | 12 +- Gemfile.lock | 24 ++-- java-buildpack.iml | 59 +++++----- lib/java_buildpack/buildpack.rb | 40 +++---- lib/java_buildpack/container/dist_zip_like.rb | 8 +- .../container/tomcat/tomcat_geode_store.rb | 6 +- .../container/tomcat/tomcat_redis_store.rb | 18 +-- .../framework/app_dynamics_agent.rb | 2 +- .../azure_application_insights_agent.rb | 2 +- .../framework/dyadic_ekm_security_provider.rb | 2 +- .../framework/dynatrace_appmon_agent.rb | 2 +- .../framework/dynatrace_one_agent.rb | 2 +- .../framework/google_stackdriver_debugger.rb | 2 +- .../framework/google_stackdriver_profiler.rb | 8 +- .../framework/introscope_agent.rb | 10 +- lib/java_buildpack/framework/jacoco_agent.rb | 12 +- .../framework/luna_security_provider.rb | 2 +- lib/java_buildpack/framework/metric_writer.rb | 2 +- .../framework/new_relic_agent.rb | 2 +- .../protect_app_security_provider.rb | 2 +- .../framework/riverbed_appinternals_agent.rb | 2 +- .../framework/sky_walking_agent.rb | 4 +- .../framework/spring_insight.rb | 2 +- lib/java_buildpack/framework/takipi_agent.rb | 2 +- .../framework/your_kit_profiler.rb | 2 +- lib/java_buildpack/jre/jvmkill_agent.rb | 2 +- .../jre/open_jdk_like_memory_calculator.rb | 2 +- .../repository/repository_index.rb | 2 +- rakelib/dependency_cache_task.rb | 8 +- rakelib/versions_task.rb | 104 +++++++++--------- spec/application_helper.rb | 14 +-- spec/bin/detect_spec.rb | 2 +- spec/component_helper.rb | 6 +- spec/java_buildpack/buildpack_spec.rb | 10 +- spec/java_buildpack/buildpack_version_spec.rb | 10 +- .../component/base_component_spec.rb | 6 +- .../component/immutable_java_home_spec.rb | 4 +- .../component/modular_component_spec.rb | 6 +- .../java_buildpack/component/services_spec.rb | 54 ++++----- .../versioned_dependency_component_spec.rb | 6 +- spec/java_buildpack/container/groovy_spec.rb | 2 +- .../container/spring_boot_cli_spec.rb | 2 +- .../tomcat_external_configuration_spec.rb | 4 +- .../tomcat/tomcat_geode_store_spec.rb | 42 +++---- .../container/tomcat/tomcat_instance_spec.rb | 18 +-- .../tomcat/tomcat_redis_store_spec.rb | 14 +-- spec/java_buildpack/container/tomcat_spec.rb | 12 +- .../framework/app_dynamics_agent_spec.rb | 4 +- .../framework/contrast_security_agent_spec.rb | 6 +- .../dyadic_ekm_security_provider_spec.rb | 12 +- .../framework/dynatrace_appmon_agent_spec.rb | 2 +- .../framework/dynatrace_one_agent_spec.rb | 14 +-- .../framework/introscope_agent_spec.rb | 4 +- .../framework/jacoco_agent_spec.rb | 4 +- .../heap_dump_folder_spec.rb | 6 +- .../framework/java_memory_assistant_spec.rb | 6 +- .../framework/jrebel_agent_spec.rb | 4 +- .../framework/luna_security_provider_spec.rb | 20 ++-- .../framework/metric_writer_spec.rb | 4 +- .../spring_auto_reconfiguration_spec.rb | 4 +- .../framework/spring_insight_spec.rb | 22 ++-- spec/java_buildpack/jre/ibm_jre_spec.rb | 4 +- .../open_jdk_like_memory_calculator_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_spec.rb | 6 +- .../repository/configured_item_spec.rb | 8 +- .../util/cache/application_cache_spec.rb | 4 +- .../util/cache/download_cache_spec.rb | 24 ++-- .../util/configuration_utils_spec.rb | 22 ++-- spec/java_buildpack/util/shell_spec.rb | 2 +- .../util/spring_boot_utils_spec.rb | 2 +- 77 files changed, 406 insertions(+), 394 deletions(-) rename .idea/runConfigurations/{All_Tests__2_3_.xml => All_Tests__2_6_.xml} (87%) rename .idea/runConfigurations/{Without_Integration_Tests__2_3_.xml => Without_Integration_Tests__2_6_.xml} (87%) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 46f83bd0d3..2afc9d8a0d 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -5,7 +5,6 @@ - + \ No newline at end of file diff --git a/.idea/runConfigurations/All_Tests__2_4_.xml b/.idea/runConfigurations/All_Tests__2_4_.xml index ef434cddc0..dd69d62638 100644 --- a/.idea/runConfigurations/All_Tests__2_4_.xml +++ b/.idea/runConfigurations/All_Tests__2_4_.xml @@ -1,11 +1,11 @@ - - + + - + @@ -31,6 +31,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/All_Tests__2_5_.xml b/.idea/runConfigurations/All_Tests__2_5_.xml index 8495593f65..0b16afa3c6 100644 --- a/.idea/runConfigurations/All_Tests__2_5_.xml +++ b/.idea/runConfigurations/All_Tests__2_5_.xml @@ -1,11 +1,11 @@ - - + + - + @@ -37,6 +37,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/All_Tests__2_3_.xml b/.idea/runConfigurations/All_Tests__2_6_.xml similarity index 87% rename from .idea/runConfigurations/All_Tests__2_3_.xml rename to .idea/runConfigurations/All_Tests__2_6_.xml index 12db3db056..5fb2fb47f5 100644 --- a/.idea/runConfigurations/All_Tests__2_3_.xml +++ b/.idea/runConfigurations/All_Tests__2_6_.xml @@ -1,11 +1,11 @@ - - + - + + - + @@ -31,6 +31,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml index 0582ee9adb..9bf6e6c3fa 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml @@ -1,11 +1,11 @@ - - + + - + @@ -31,6 +31,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml index 12f1e6ad3e..7c6717a82a 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml @@ -1,11 +1,11 @@ - - + + - + @@ -37,6 +37,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml similarity index 87% rename from .idea/runConfigurations/Without_Integration_Tests__2_3_.xml rename to .idea/runConfigurations/Without_Integration_Tests__2_6_.xml index 18a752c5d9..43a6b4158c 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml @@ -1,11 +1,11 @@ - - + - + + - + @@ -31,6 +31,8 @@ - + + \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 1f7a766a31..0fa6131d0e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,15 +7,15 @@ GEM crack (0.4.3) safe_yaml (~> 1.0.0) diff-lcs (1.3) - hashdiff (0.3.7) - jaro_winkler (1.5.1) + hashdiff (0.3.8) + jaro_winkler (1.5.2) parallel (1.12.1) - parser (2.5.1.2) + parser (2.5.3.0) ast (~> 2.4.0) powerpack (0.1.2) public_suffix (3.0.3) rainbow (3.0.0) - rake (12.3.1) + rake (12.3.2) redcarpet (3.4.0) rspec (3.8.0) rspec-core (~> 3.8.0) @@ -23,31 +23,31 @@ GEM rspec-mocks (~> 3.8.0) rspec-core (3.8.0) rspec-support (~> 3.8.0) - rspec-expectations (3.8.1) + rspec-expectations (3.8.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-mocks (3.8.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) - rubocop (0.59.1) + rubocop (0.62.0) jaro_winkler (~> 1.5.1) parallel (~> 1.10) parser (>= 2.5, != 2.5.1.1) powerpack (~> 0.1) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.29.1) - rubocop (>= 0.58.0) + unicode-display_width (~> 1.4.0) + rubocop-rspec (1.31.0) + rubocop (>= 0.60.0) ruby-progressbar (1.10.0) rubyzip (1.2.2) safe_yaml (1.0.4) tee (1.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - unicode-display_width (1.4.0) - webmock (3.4.2) + unicode-display_width (1.4.1) + webmock (3.5.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff @@ -69,4 +69,4 @@ DEPENDENCIES yard BUNDLED WITH - 1.16.1 + 2.0.1 diff --git a/java-buildpack.iml b/java-buildpack.iml index 01930c6c66..2b92fdf531 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -265,36 +265,37 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 03b8d29d40..36841333a8 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -94,8 +94,8 @@ def release command = commands.flatten.compact.join(' && ') payload = { - 'addons' => [], - 'config_vars' => {}, + 'addons' => [], + 'config_vars' => {}, 'default_process_types' => { 'web' => command, 'task' => command } }.to_yaml @@ -115,7 +115,7 @@ def release private_constant :BUILDPACK_MESSAGE, :LOAD_ROOT def initialize(app_dir, application) - @logger = Logging::LoggerFactory.instance.get_logger Buildpack + @logger = Logging::LoggerFactory.instance.get_logger Buildpack @buildpack_version = BuildpackVersion.new log_arguments @@ -125,19 +125,19 @@ def initialize(app_dir, application) @java_opts = Component::JavaOpts.new(app_dir) - mutable_java_home = Component::MutableJavaHome.new + mutable_java_home = Component::MutableJavaHome.new immutable_java_home = Component::ImmutableJavaHome.new mutable_java_home, app_dir component_info = { - 'additional_libraries' => Component::AdditionalLibraries.new(app_dir), - 'app_dir' => app_dir, - 'application' => application, - 'env_vars' => Component::EnvironmentVariables.new(app_dir), + 'additional_libraries' => Component::AdditionalLibraries.new(app_dir), + 'app_dir' => app_dir, + 'application' => application, + 'env_vars' => Component::EnvironmentVariables.new(app_dir), 'extension_directories' => Component::ExtensionDirectories.new(app_dir), - 'java_opts' => @java_opts, - 'networking' => Component::Networking.new, - 'root_libraries' => Component::RootLibraries.new(app_dir), - 'security_providers' => Component::SecurityProviders.new + 'java_opts' => @java_opts, + 'networking' => Component::Networking.new, + 'root_libraries' => Component::RootLibraries.new(app_dir), + 'security_providers' => Component::SecurityProviders.new } instantiate_components(mutable_java_home, immutable_java_home, component_info) @@ -146,7 +146,7 @@ def initialize(app_dir, application) def instantiate_components(mutable_java_home, immutable_java_home, component_info) components = JavaBuildpack::Util::ConfigurationUtils.load 'components' - @jres = instantiate(components['jres'], mutable_java_home, component_info) + @jres = instantiate(components['jres'], mutable_java_home, component_info) @frameworks = instantiate(components['frameworks'], immutable_java_home, component_info) @containers = instantiate(components['containers'], immutable_java_home, component_info) end @@ -158,7 +158,7 @@ def component_detection(type, components, unique) def detection(type, components, unique) detected = [] - tags = [] + tags = [] components.each do |component| result = component.detect @@ -183,13 +183,13 @@ def instantiate(components, java_home, component_info) component_id = component.split('::').last.snake_case context = { - application: component_info['application'], + application: component_info['application'], configuration: Util::ConfigurationUtils.load(component_id), - droplet: Component::Droplet.new(component_info['additional_libraries'], component_id, - component_info['env_vars'], component_info['extension_directories'], - java_home, component_info['java_opts'], component_info['networking'], - component_info['app_dir'], component_info['root_libraries'], - component_info['security_providers']) + droplet: Component::Droplet.new(component_info['additional_libraries'], component_id, + component_info['env_vars'], component_info['extension_directories'], + java_home, component_info['java_opts'], component_info['networking'], + component_info['app_dir'], component_info['root_libraries'], + component_info['security_providers']) } component.constantize.new(context) end diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 86ce620f66..a1aeb685be 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -76,9 +76,9 @@ def supports? private - PATTERN_APP_CLASSPATH = /^declare -r app_classpath=\"(.*)\"$/ + PATTERN_APP_CLASSPATH = /^declare -r app_classpath=\"(.*)\"$/.freeze - PATTERN_CLASSPATH = /^CLASSPATH=(.*)$/ + PATTERN_CLASSPATH = /^CLASSPATH=(.*)$/.freeze private_constant :PATTERN_APP_CLASSPATH, :PATTERN_CLASSPATH @@ -103,9 +103,9 @@ def augment_classpath(content) def augment_classpath_content content = start_script(root).read - if content =~ PATTERN_CLASSPATH + if content.match? PATTERN_CLASSPATH augment_classpath content - elsif content =~ PATTERN_APP_CLASSPATH + elsif content.match? PATTERN_APP_CLASSPATH augment_app_classpath content end end diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 3e603973c6..8b4599e5ed 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -59,7 +59,7 @@ def supports? private - FILTER = /session-replication/ + FILTER = /session-replication/.freeze KEY_LOCATORS = 'locators' KEY_USERS = 'users' @@ -157,7 +157,7 @@ def mutate_context puts ' Adding Geode-based Session Replication' document = read_xml context_xml - context = REXML::XPath.match(document, '/Context').first + context = REXML::XPath.match(document, '/Context').first add_manager context @@ -167,7 +167,7 @@ def mutate_context def mutate_server document = read_xml server_xml - server = REXML::XPath.match(document, '/Server').first + server = REXML::XPath.match(document, '/Server').first add_listener server diff --git a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb index ff9b04fb24..4164cc5c3c 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb @@ -47,7 +47,7 @@ def supports? private - FILTER = /session-replication/ + FILTER = /session-replication/.freeze FLUSH_VALVE_CLASS_NAME = 'com.gopivotal.manager.SessionFlushValve' @@ -76,12 +76,12 @@ def add_store(manager) KEY_PASSWORD)['credentials'] manager.add_element 'Store', - 'className' => REDIS_STORE_CLASS_NAME, - 'host' => credentials[KEY_HOST_NAME] || credentials[KEY_HOST], - 'port' => credentials[KEY_PORT], - 'database' => @configuration['database'], - 'password' => credentials[KEY_PASSWORD], - 'timeout' => @configuration['timeout'], + 'className' => REDIS_STORE_CLASS_NAME, + 'host' => credentials[KEY_HOST_NAME] || credentials[KEY_HOST], + 'port' => credentials[KEY_PORT], + 'database' => @configuration['database'], + 'password' => credentials[KEY_PASSWORD], + 'timeout' => @configuration['timeout'], 'connectionPoolSize' => @configuration['connection_pool_size'] end @@ -90,7 +90,7 @@ def add_valve(context) end def formatter - formatter = REXML::Formatters::Pretty.new(4) + formatter = REXML::Formatters::Pretty.new(4) formatter.compact = true formatter end @@ -103,7 +103,7 @@ def mutate_context puts ' Adding Redis-based Session Replication' document = read_xml context_xml - context = REXML::XPath.match(document, '/Context').first + context = REXML::XPath.match(document, '/Context').first add_valve context add_manager context diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index f68ca3da60..560aaa55da 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -56,7 +56,7 @@ def supports? private - FILTER = /app[-]?dynamics/ + FILTER = /app[-]?dynamics/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/framework/azure_application_insights_agent.rb b/lib/java_buildpack/framework/azure_application_insights_agent.rb index 69351502d4..d2179debf6 100644 --- a/lib/java_buildpack/framework/azure_application_insights_agent.rb +++ b/lib/java_buildpack/framework/azure_application_insights_agent.rb @@ -47,7 +47,7 @@ def supports? @application.services.one_service? FILTER, INSTRUMENTATION_KEY end - FILTER = /azure-application-insights/ + FILTER = /azure-application-insights/.freeze INSTRUMENTATION_KEY = 'instrumentation_key' diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index 7d5ae0e452..7f845b20a3 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -62,7 +62,7 @@ def supports? private - FILTER = /dyadic/ + FILTER = /dyadic/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb index 3b3757d855..5dbbdf91f0 100644 --- a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb @@ -49,7 +49,7 @@ def supports? private - FILTER = /dynatrace/ + FILTER = /dynatrace/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 6719b88269..d2b5a7aaf5 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -92,7 +92,7 @@ def supports? ENVIRONMENTID = 'environmentid' - FILTER = /dynatrace/ + FILTER = /dynatrace/.freeze SKIP_ERRORS = 'skiperrors' diff --git a/lib/java_buildpack/framework/google_stackdriver_debugger.rb b/lib/java_buildpack/framework/google_stackdriver_debugger.rb index e84592bbac..e26f20a718 100644 --- a/lib/java_buildpack/framework/google_stackdriver_debugger.rb +++ b/lib/java_buildpack/framework/google_stackdriver_debugger.rb @@ -52,7 +52,7 @@ def supports? @application.services.one_service? FILTER, PRIVATE_KEY_DATA end - FILTER = /google-stackdriver-debugger/ + FILTER = /google-stackdriver-debugger/.freeze PRIVATE_KEY_DATA = 'PrivateKeyData' diff --git a/lib/java_buildpack/framework/google_stackdriver_profiler.rb b/lib/java_buildpack/framework/google_stackdriver_profiler.rb index 856cd38225..ae5b041e6c 100644 --- a/lib/java_buildpack/framework/google_stackdriver_profiler.rb +++ b/lib/java_buildpack/framework/google_stackdriver_profiler.rb @@ -39,9 +39,9 @@ def release java_opts .add_agentpath_with_props(@droplet.sandbox + 'profiler_java_agent.so', - '--logtostderr' => 1, - '-cprof_project_id' => project_id, - '-cprof_service' => application_name, + '--logtostderr' => 1, + '-cprof_project_id' => project_id, + '-cprof_service' => application_name, '-cprof_service_version' => application_version) @droplet.environment_variables.add_environment_variable 'GOOGLE_APPLICATION_CREDENTIALS', json_file @@ -54,7 +54,7 @@ def supports? @application.services.one_service? FILTER, PRIVATE_KEY_DATA end - FILTER = /google-stackdriver-profiler/ + FILTER = /google-stackdriver-profiler/.freeze PRIVATE_KEY_DATA = 'PrivateKeyData' diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index c1d92d9703..a6e9d716c5 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -35,7 +35,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release credentials = @application.services.find_service(FILTER, %w[agent_manager_url url])['credentials'] - java_opts = @droplet.java_opts + java_opts = @droplet.java_opts java_opts .add_javaagent(agent_jar) @@ -60,7 +60,7 @@ def supports? private - FILTER = /introscope/ + FILTER = /introscope/.freeze private_constant :FILTER @@ -111,9 +111,9 @@ def protocol_mapping(protocol) socket_factory_base = 'com.wily.isengard.postofficehub.link.net.' protocol_socket_factory = { - '' => socket_factory_base + 'DefaultSocketFactory', - 'ssl' => socket_factory_base + 'SSLSocketFactory', - 'http' => socket_factory_base + 'HttpTunnelingSocketFactory', + '' => socket_factory_base + 'DefaultSocketFactory', + 'ssl' => socket_factory_base + 'SSLSocketFactory', + 'http' => socket_factory_base + 'HttpTunnelingSocketFactory', 'https' => socket_factory_base + 'HttpsTunnelingSocketFactory' } diff --git a/lib/java_buildpack/framework/jacoco_agent.rb b/lib/java_buildpack/framework/jacoco_agent.rb index 8bd3f36e69..9a33f13d27 100644 --- a/lib/java_buildpack/framework/jacoco_agent.rb +++ b/lib/java_buildpack/framework/jacoco_agent.rb @@ -31,16 +31,16 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, ADDRESS)['credentials'] - properties = { - 'address' => credentials[ADDRESS], - 'output' => 'tcpclient', + credentials = @application.services.find_service(FILTER, ADDRESS)['credentials'] + properties = { + 'address' => credentials[ADDRESS], + 'output' => 'tcpclient', 'sessionid' => '$CF_INSTANCE_GUID' } properties['excludes'] = credentials['excludes'] if credentials.key? 'excludes' properties['includes'] = credentials['includes'] if credentials.key? 'includes' - properties['port'] = credentials['port'] if credentials.key? 'port' + properties['port'] = credentials['port'] if credentials.key? 'port' @droplet.java_opts.add_javaagent_with_props(@droplet.sandbox + 'jacocoagent.jar', properties) end @@ -54,7 +54,7 @@ def supports? ADDRESS = 'address' - FILTER = /jacoco/ + FILTER = /jacoco/.freeze private_constant :ADDRESS, :FILTER diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 7a794dc319..ece9633cf6 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -62,7 +62,7 @@ def supports? private - FILTER = /luna/ + FILTER = /luna/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/framework/metric_writer.rb b/lib/java_buildpack/framework/metric_writer.rb index a4923da208..41fbf1ea86 100644 --- a/lib/java_buildpack/framework/metric_writer.rb +++ b/lib/java_buildpack/framework/metric_writer.rb @@ -54,7 +54,7 @@ def supports? ENDPOINT = 'endpoint' - FILTER = /metrics-forwarder/ + FILTER = /metrics-forwarder/.freeze private_constant :ACCESS_KEY, :ENDPOINT, :FILTER diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 9677cd5a8e..89a9cc69e9 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -54,7 +54,7 @@ def supports? private - FILTER = /newrelic/ + FILTER = /newrelic/.freeze LICENSE_KEY = 'licenseKey' diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb index cece9cfc11..583080212f 100644 --- a/lib/java_buildpack/framework/protect_app_security_provider.rb +++ b/lib/java_buildpack/framework/protect_app_security_provider.rb @@ -74,7 +74,7 @@ def supports? private - FILTER = /protectapp/ + FILTER = /protectapp/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb index adce6ea2ce..984ff70fe8 100644 --- a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb +++ b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb @@ -57,7 +57,7 @@ def supports? private - FILTER = /appinternals/ + FILTER = /appinternals/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/framework/sky_walking_agent.rb b/lib/java_buildpack/framework/sky_walking_agent.rb index 0ab38380c9..abf779d13b 100644 --- a/lib/java_buildpack/framework/sky_walking_agent.rb +++ b/lib/java_buildpack/framework/sky_walking_agent.rb @@ -34,7 +34,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release credentials = @application.services.find_service(FILTER, 'servers')['credentials'] - java_opts = @droplet.java_opts + java_opts = @droplet.java_opts java_opts.add_javaagent(@droplet.sandbox + 'skywalking-agent.jar') application_name java_opts, credentials @@ -55,7 +55,7 @@ def supports? private - FILTER = /sky[-]?walking/ + FILTER = /sky[-]?walking/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/framework/spring_insight.rb b/lib/java_buildpack/framework/spring_insight.rb index 49d3df93ea..e75bc23c71 100644 --- a/lib/java_buildpack/framework/spring_insight.rb +++ b/lib/java_buildpack/framework/spring_insight.rb @@ -74,7 +74,7 @@ def id(version) private - FILTER = /p-insight/ + FILTER = /p-insight/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index 931ecf601d..44ccf6a9b9 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -60,7 +60,7 @@ def supports? COLLECTOR_HOST = 'collector_host' - FILTER = /takipi/ + FILTER = /takipi/.freeze SECRET_KEY = 'secret_key' diff --git a/lib/java_buildpack/framework/your_kit_profiler.rb b/lib/java_buildpack/framework/your_kit_profiler.rb index 4a5288de90..5d38d7df4e 100644 --- a/lib/java_buildpack/framework/your_kit_profiler.rb +++ b/lib/java_buildpack/framework/your_kit_profiler.rb @@ -45,7 +45,7 @@ def release @droplet .java_opts .add_agentpath_with_props(file_name, - 'dir' => snapshots, 'logdir' => logs, + 'dir' => snapshots, 'logdir' => logs, 'port' => port, 'sessionname' => session_name) end diff --git a/lib/java_buildpack/jre/jvmkill_agent.rb b/lib/java_buildpack/jre/jvmkill_agent.rb index 2a34a22f84..0438748bf2 100644 --- a/lib/java_buildpack/jre/jvmkill_agent.rb +++ b/lib/java_buildpack/jre/jvmkill_agent.rb @@ -54,7 +54,7 @@ def supports? private - FILTER = /heap-dump/ + FILTER = /heap-dump/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 9d7618e556..0b20ca9a0c 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -98,7 +98,7 @@ def memory_calculator end def memory_calculator_tar - platform = `uname -s` =~ /Darwin/ ? 'darwin' : 'linux' + platform = `uname -s`.match?(/Darwin/) ? 'darwin' : 'linux' @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{platform}" end diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 84298e7587..81364b1cca 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -87,7 +87,7 @@ def platform if redhat_release.exist? tokens = redhat_release.read.match(/(\w+) (?:Linux )?release (\d+)/) "#{tokens[1].downcase}#{tokens[2]}" - elsif `uname -s` =~ /Darwin/ + elsif `uname -s`.match?(/Darwin/) 'mountainlion' elsif !`which lsb_release 2> /dev/null`.empty? `lsb_release -cs`.strip diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 9f78a97fa7..056fc82492 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -48,18 +48,18 @@ def initialize private - ARCHITECTURE_PATTERN = /\{architecture\}/ + ARCHITECTURE_PATTERN = /\{architecture\}/.freeze - DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/ + DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/.freeze - PLATFORM_PATTERN = /\{platform\}/ + PLATFORM_PATTERN = /\{platform\}/.freeze private_constant :ARCHITECTURE_PATTERN, :DEFAULT_REPOSITORY_ROOT_PATTERN, :PLATFORM_PATTERN def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at raw.map(&block) - elsif raw[:uri] =~ pattern + elsif raw[:uri].match? pattern candidates.map do |candidate| dup = raw.clone dup[key] = candidate diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 9cc89e2ec8..d0d21203a0 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -46,54 +46,54 @@ def initialize private - ARCHITECTURE_PATTERN = /\{architecture\}/ + ARCHITECTURE_PATTERN = /\{architecture\}/.freeze - DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/ + DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/.freeze NAME_MAPPINGS = { - 'access_logging_support' => 'Tomcat Access Logging Support', - 'agent' => 'Java Memory Assistant Agent', - 'app_dynamics_agent' => 'AppDynamics Agent', + 'access_logging_support' => 'Tomcat Access Logging Support', + 'agent' => 'Java Memory Assistant Agent', + 'app_dynamics_agent' => 'AppDynamics Agent', 'azure_application_insights_agent' => 'Azure Application Insights Agent', - 'clean_up' => 'Java Memory Assistant Clean Up', - 'client_certificate_mapper' => 'Client Certificate Mapper', - 'container_customizer' => 'Spring Boot Container Customizer', - 'container_security_provider' => 'Container Security Provider', - 'contrast_security_agent' => 'Contrast Security Agent', - 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', - 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', - 'dynatrace_one_agent' => 'Dynatrace OneAgent', - 'geode_store' => 'Geode Tomcat Session Store', - 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', - 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', - 'groovy' => 'Groovy', - 'introscope_agent' => 'CA Introscope APM Framework', - 'jacoco_agent' => 'JaCoCo Agent', - 'jprofiler_profiler' => 'JProfiler Profiler', - 'jre' => 'OpenJDK JRE', - 'jre-11' => 'OpenJDK JRE 11', - 'jrebel_agent' => 'JRebel Agent', - 'jvmkill_agent' => 'jvmkill Agent', - 'lifecycle_support' => 'Tomcat Lifecycle Support', - 'logging_support' => 'Tomcat Logging Support', - 'luna_security_provider' => 'Gemalto Luna Security Provider', - 'maria_db_jdbc' => 'MariaDB JDBC Driver', - 'memory_calculator' => 'Memory Calculator', - 'metric_writer' => 'Metric Writer', - 'new_relic_agent' => 'New Relic Agent', - 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', - 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', - 'redis_store' => 'Redis Session Store', - 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', - 'sky_walking_agent' => 'SkyWalking', - 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', - 'spring_boot_cli' => 'Spring Boot CLI', - 'takipi_agent' => 'Takipi Agent', - 'tomcat' => 'Tomcat', - 'your_kit_profiler' => 'YourKit Profiler' + 'clean_up' => 'Java Memory Assistant Clean Up', + 'client_certificate_mapper' => 'Client Certificate Mapper', + 'container_customizer' => 'Spring Boot Container Customizer', + 'container_security_provider' => 'Container Security Provider', + 'contrast_security_agent' => 'Contrast Security Agent', + 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', + 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', + 'dynatrace_one_agent' => 'Dynatrace OneAgent', + 'geode_store' => 'Geode Tomcat Session Store', + 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', + 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', + 'groovy' => 'Groovy', + 'introscope_agent' => 'CA Introscope APM Framework', + 'jacoco_agent' => 'JaCoCo Agent', + 'jprofiler_profiler' => 'JProfiler Profiler', + 'jre' => 'OpenJDK JRE', + 'jre-11' => 'OpenJDK JRE 11', + 'jrebel_agent' => 'JRebel Agent', + 'jvmkill_agent' => 'jvmkill Agent', + 'lifecycle_support' => 'Tomcat Lifecycle Support', + 'logging_support' => 'Tomcat Logging Support', + 'luna_security_provider' => 'Gemalto Luna Security Provider', + 'maria_db_jdbc' => 'MariaDB JDBC Driver', + 'memory_calculator' => 'Memory Calculator', + 'metric_writer' => 'Metric Writer', + 'new_relic_agent' => 'New Relic Agent', + 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', + 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', + 'redis_store' => 'Redis Session Store', + 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', + 'sky_walking_agent' => 'SkyWalking', + 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', + 'spring_boot_cli' => 'Spring Boot CLI', + 'takipi_agent' => 'Takipi Agent', + 'tomcat' => 'Tomcat', + 'your_kit_profiler' => 'YourKit Profiler' }.freeze - PLATFORM_PATTERN = /\{platform\}/ + PLATFORM_PATTERN = /\{platform\}/.freeze private_constant :ARCHITECTURE_PATTERN, :DEFAULT_REPOSITORY_ROOT_PATTERN, :NAME_MAPPINGS, :PLATFORM_PATTERN @@ -101,10 +101,10 @@ def initialize def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at raw.map(&block) - elsif raw[:uri] =~ pattern + elsif raw[:uri].match? pattern candidates.map do |candidate| - dup = raw.clone - dup[key] = candidate + dup = raw.clone + dup[key] = candidate dup[:uri] = raw[:uri].gsub pattern, candidate dup @@ -153,7 +153,7 @@ def configurations(component_id, configuration, sub_component_id = nil) configurations = [] if repository_configuration?(configuration) - configuration['component_id'] = component_id + configuration['component_id'] = component_id configuration['sub_component_id'] = sub_component_id if sub_component_id if component_id == 'open_jdk_jre' && sub_component_id == 'jre' @@ -178,7 +178,7 @@ def default_repository_root def get_from_cache(cache, configuration, index_configuration) cache.get(index_configuration[:uri]) do |f| - index = YAML.safe_load f + index = YAML.safe_load f found_version = version(configuration, index) if found_version.nil? @@ -193,7 +193,7 @@ def get_from_cache(cache, configuration, index_configuration) def dependency_versions dependency_versions = [] - cache = JavaBuildpack::Util::Cache::DownloadCache.new + cache = JavaBuildpack::Util::Cache::DownloadCache.new configurations = component_ids.map { |component_id| component_configuration(component_id) }.flatten configurations.each do |configuration| @@ -206,9 +206,9 @@ def dependency_versions raise "Unable to resolve name for '#{id}'" unless name dependency_versions << { - 'id' => id, - 'name' => name, - 'uri' => uri, + 'id' => id, + 'name' => name, + 'uri' => uri, 'version' => version } end @@ -280,7 +280,7 @@ def version_yaml_task def versions { - 'buildpack' => Package.version, + 'buildpack' => Package.version, 'dependencies' => dependency_versions } end diff --git a/spec/application_helper.rb b/spec/application_helper.rb index 6f9bcb176c..f5c952a920 100644 --- a/spec/application_helper.rb +++ b/spec/application_helper.rb @@ -27,7 +27,7 @@ previous_environment = ENV.to_hash let(:environment) do - { 'test-key' => 'test-value', 'VCAP_APPLICATION' => vcap_application.to_json, + { 'test-key' => 'test-value', 'VCAP_APPLICATION' => vcap_application.to_json, 'VCAP_SERVICES' => vcap_services.to_json } end @@ -48,16 +48,16 @@ let(:services) { application.services } let(:vcap_application) do - { 'application_id' => 'test-application-id', - 'application_name' => 'test-application-name', + { 'application_id' => 'test-application-id', + 'application_name' => 'test-application-name', 'application_version' => 'test-application-version', - 'space_id' => 'test-space-id', - 'space_name' => 'test-space-name' } + 'space_id' => 'test-space-id', + 'space_name' => 'test-space-name' } end let(:vcap_services) do - { 'test-service-n/a' => [{ 'name' => 'test-service-name', 'label' => 'test-service-n/a', - 'tags' => ['test-service-tag'], 'plan' => 'test-plan', + { 'test-service-n/a' => [{ 'name' => 'test-service-name', 'label' => 'test-service-n/a', + 'tags' => ['test-service-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri' } }] } end diff --git a/spec/bin/detect_spec.rb b/spec/bin/detect_spec.rb index 891b3377b3..0580fa3cde 100644 --- a/spec/bin/detect_spec.rb +++ b/spec/bin/detect_spec.rb @@ -38,7 +38,7 @@ end it 'truncates long detect strings', - app_fixture: 'integration_valid', + app_fixture: 'integration_valid', buildpack_fixture: 'integration_long_detect_tag' do run("bin/detect #{app_dir}") do |status| diff --git a/spec/component_helper.rb b/spec/component_helper.rb index 6b2ed8e000..0e7f3f2119 100644 --- a/spec/component_helper.rb +++ b/spec/component_helper.rb @@ -40,10 +40,10 @@ let(:configuration) { {} } let(:context) do - { application: application, + { application: application, component_name: described_class.to_s.split('::').last.space_case, - configuration: configuration, - droplet: droplet } + configuration: configuration, + droplet: droplet } end let(:uri) { 'test-uri' } diff --git a/spec/java_buildpack/buildpack_spec.rb b/spec/java_buildpack/buildpack_spec.rb index 6d1b290bf1..d52c561fcc 100644 --- a/spec/java_buildpack/buildpack_spec.rb +++ b/spec/java_buildpack/buildpack_spec.rb @@ -51,7 +51,7 @@ .to receive(:load).with('components').and_return( 'containers' => %w[Test::StubContainer1 Test::StubContainer2], 'frameworks' => %w[Test::StubFramework1 Test::StubFramework2], - 'jres' => %w[Test::StubJre1 Test::StubJre2] + 'jres' => %w[Test::StubJre1 Test::StubJre2] ) allow(Test::StubContainer1).to receive(:new).and_return(stub_container1) @@ -92,7 +92,7 @@ .and_return( 'containers' => [], 'frameworks' => ['JavaBuildpack::Framework::JavaOpts'], - 'jres' => [] + 'jres' => [] ) end @@ -129,9 +129,9 @@ expect(stub_jre2).not_to have_received(:release) expect(buildpack.release) - .to eq({ 'addons' => [], - 'config_vars' => {}, - 'default_process_types' => { 'web' => 'JAVA_OPTS="" && test-command', + .to eq({ 'addons' => [], + 'config_vars' => {}, + 'default_process_types' => { 'web' => 'JAVA_OPTS="" && test-command', 'task' => 'JAVA_OPTS="" && test-command' } }.to_yaml) end diff --git a/spec/java_buildpack/buildpack_version_spec.rb b/spec/java_buildpack/buildpack_version_spec.rb index 28669a26c4..d4ad23e45d 100644 --- a/spec/java_buildpack/buildpack_version_spec.rb +++ b/spec/java_buildpack/buildpack_version_spec.rb @@ -35,8 +35,8 @@ end it 'creates offline version string from config/version.yml', - log_level: 'DEBUG', - configuration: { 'hash' => 'test-hash', 'offline' => true, + log_level: 'DEBUG', + configuration: { 'hash' => 'test-hash', 'offline' => true, 'remote' => 'test-remote', 'version' => 'test-version' } do expect(buildpack_version.to_s).to match(/test-version (offline) | test-remote#test-hash/) @@ -45,8 +45,8 @@ end it 'creates online version string from config/version.yml', - log_level: 'DEBUG', - configuration: { 'hash' => 'test-hash', 'offline' => false, + log_level: 'DEBUG', + configuration: { 'hash' => 'test-hash', 'offline' => false, 'remote' => 'test-remote', 'version' => 'test-version' } do expect(buildpack_version.to_s).to match(/test-version | test-remote#test-hash/) @@ -85,7 +85,7 @@ end it 'creates a has from the values', - configuration: { 'hash' => 'test-hash', 'offline' => true, + configuration: { 'hash' => 'test-hash', 'offline' => true, 'remote' => 'test-remote', 'version' => 'test-version' } do |example| allow_any_instance_of(described_class).to receive(:system).with('which git > /dev/null').and_return(false) diff --git a/spec/java_buildpack/component/base_component_spec.rb b/spec/java_buildpack/component/base_component_spec.rb index bf532b5e01..8f638b6e0d 100644 --- a/spec/java_buildpack/component/base_component_spec.rb +++ b/spec/java_buildpack/component/base_component_spec.rb @@ -41,9 +41,9 @@ end it 'fails if methods are unimplemented' do - expect { component.detect }.to raise_error - expect { component.compile }.to raise_error - expect { component.release }.to raise_error + expect { component.detect }.to raise_error RuntimeError + expect { component.compile }.to raise_error RuntimeError + expect { component.release }.to raise_error RuntimeError end it 'downloads file and yield it', diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index b8fbbb25c9..6a407950e7 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -24,10 +24,10 @@ let(:delegate) do instance_double(JavaBuildpack::Component::MutableJavaHome, - root: Pathname.new('test-java-home'), + root: Pathname.new('test-java-home'), java_8_or_later?: true, java_9_or_later?: true, - version: JavaBuildpack::Util::TokenizedVersion.new('1.2.3_u04')) + version: JavaBuildpack::Util::TokenizedVersion.new('1.2.3_u04')) end let(:immutable_java_home) { described_class.new delegate, Pathname.new('.') } diff --git a/spec/java_buildpack/component/modular_component_spec.rb b/spec/java_buildpack/component/modular_component_spec.rb index f55e40b75a..d7d0a2f7ea 100644 --- a/spec/java_buildpack/component/modular_component_spec.rb +++ b/spec/java_buildpack/component/modular_component_spec.rb @@ -25,7 +25,7 @@ let(:component) { StubModularComponent.new context } it 'fails if supports? is unimplemented' do - expect { component.supports? }.to raise_error + expect { component.supports? }.to raise_error RuntimeError end context do @@ -39,8 +39,8 @@ end it 'fails if methods are unimplemented' do - expect { component.command }.to raise_error - expect { component.sub_components(context) }.to raise_error + expect { component.command }.to raise_error RuntimeError + expect { component.sub_components(context) }.to raise_error RuntimeError end end diff --git a/spec/java_buildpack/component/services_spec.rb b/spec/java_buildpack/component/services_spec.rb index abfa5cc6a2..f7a28d3119 100644 --- a/spec/java_buildpack/component/services_spec.rb +++ b/spec/java_buildpack/component/services_spec.rb @@ -29,7 +29,7 @@ context('with single service') do let(:service_payload) do - [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] end @@ -59,7 +59,7 @@ let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan' }, - { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] end @@ -92,11 +92,11 @@ context('with single service') do let(:service_payload) do - [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', - 'device_type' => 'shared', - 'mode' => 'rw' }] }] + 'device_type' => 'shared', + 'mode' => 'rw' }] }] end it 'returns nil from find_service? if there is no service that matches' do @@ -124,14 +124,14 @@ context('with two services') do let(:service_payload) do - [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, 'volume_mounts' => [] }, - { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', - 'device_type' => 'shared', - 'mode' => 'rw' }] }] + 'device_type' => 'shared', + 'mode' => 'rw' }] }] end it 'returns nil from find_service? if there is no service that matches' do @@ -163,7 +163,7 @@ context('with single service') do let(:service_payload) do - [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] end @@ -218,7 +218,7 @@ let(:service_payload) do [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan' }, - { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + { 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] end @@ -275,7 +275,7 @@ context('with no volume mounts') do let(:service_payload) do - [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' } }] end @@ -298,8 +298,8 @@ context('with empty volume mounts') do let(:service_payload) do - [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, 'volume_mounts' => [] }] end @@ -322,11 +322,11 @@ context('with one volume mount') do let(:service_payload) do - [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', - 'device_type' => 'shared', - 'mode' => 'rw' }] }] + 'device_type' => 'shared', + 'mode' => 'rw' }] }] end it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do @@ -348,14 +348,14 @@ context('with two volume mounts') do let(:service_payload) do - [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', - 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, + [{ 'name' => 'test-name', 'label' => 'test-label', 'tags' => ['test-tag'], 'plan' => 'test-plan', + 'credentials' => { 'uri' => 'test-uri', 'h1' => 'foo', 'h2' => 'foo' }, 'volume_mounts' => [{ 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', - 'device_type' => 'shared', - 'mode' => 'rw' }, + 'device_type' => 'shared', + 'mode' => 'rw' }, { 'container_dir' => '/var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147', - 'device_type' => 'shared', - 'mode' => 'rw' }] }] + 'device_type' => 'shared', + 'mode' => 'rw' }] }] end it 'returns true from one_volume_service? if there is a matching name and empty volume_mounts' do diff --git a/spec/java_buildpack/component/versioned_dependency_component_spec.rb b/spec/java_buildpack/component/versioned_dependency_component_spec.rb index e376bc0e3b..27cb3e4ac3 100644 --- a/spec/java_buildpack/component/versioned_dependency_component_spec.rb +++ b/spec/java_buildpack/component/versioned_dependency_component_spec.rb @@ -25,9 +25,9 @@ let(:component) { StubVersionedDependencyComponent.new context } it 'fails if methods are unimplemented' do - expect { component.compile }.to raise_error - expect { component.release }.to raise_error - expect { component.supports? }.to raise_error + expect { component.compile }.to raise_error RuntimeError + expect { component.release }.to raise_error RuntimeError + expect { component.supports? }.to raise_error RuntimeError end context do diff --git a/spec/java_buildpack/container/groovy_spec.rb b/spec/java_buildpack/container/groovy_spec.rb index 0ddfc26d60..b4ea5a85d2 100644 --- a/spec/java_buildpack/container/groovy_spec.rb +++ b/spec/java_buildpack/container/groovy_spec.rb @@ -81,7 +81,7 @@ end it 'extracts Groovy from a ZIP', - app_fixture: 'container_groovy_main_method', + app_fixture: 'container_groovy_main_method', cache_fixture: 'stub-groovy.zip' do component.compile diff --git a/spec/java_buildpack/container/spring_boot_cli_spec.rb b/spec/java_buildpack/container/spring_boot_cli_spec.rb index c42f1e9133..9c252eb529 100644 --- a/spec/java_buildpack/container/spring_boot_cli_spec.rb +++ b/spec/java_buildpack/container/spring_boot_cli_spec.rb @@ -83,7 +83,7 @@ end it 'extracts Spring Boot CLI from a ZIP', - app_fixture: 'container_spring_boot_cli_valid_app', + app_fixture: 'container_spring_boot_cli_valid_app', cache_fixture: 'stub-spring-boot-cli.tar.gz' do component.compile diff --git a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb index 3ff0eae4ee..3289790934 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb @@ -30,7 +30,7 @@ end it 'does guarantee that internet access is available when downloading', - app_fixture: 'container_tomcat', + app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat-external-configuration.tar.gz' do expect_any_instance_of(JavaBuildpack::Util::Cache::InternetAvailability) @@ -40,7 +40,7 @@ end it 'extracts Tomcat external configuration files from a GZipped TAR', - app_fixture: 'container_tomcat', + app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat-external-configuration.tar.gz' do component.compile diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index 2b6a58e8c6..66ea79205b 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -25,8 +25,8 @@ let(:component_id) { 'tomcat' } let(:configuration) do - { 'database' => 'test-database', - 'timeout' => 'test-timeout', + { 'database' => 'test-database', + 'timeout' => 'test-timeout', 'connection_pool_size' => 'test-connection-pool-size' } end @@ -42,13 +42,13 @@ 'credentials' => { 'locators' => ['some-locator[some-port]', 'some-other-locator[some-other-port]'], 'users' => - [ - { - 'password' => 'some-password', - 'username' => 'some-username', - 'roles' => ['cluster_operator'] - } - ] + [ + { + 'password' => 'some-password', + 'username' => 'some-username', + 'roles' => ['cluster_operator'] + } + ] } ) @@ -59,7 +59,7 @@ end it 'copies resources', - app_fixture: 'container_tomcat_geode_store', + app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store.tar' do component.compile @@ -69,7 +69,7 @@ end it 'mutates context.xml', - app_fixture: 'container_tomcat_geode_store', + app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store.tar' do component.compile @@ -79,7 +79,7 @@ end it 'mutates server.xml', - app_fixture: 'container_tomcat_geode_store', + app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store.tar' do component.compile @@ -89,7 +89,7 @@ end it 'adds a cache-client.xml', - app_fixture: 'container_tomcat_geode_store', + app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store.tar' do component.compile @@ -99,7 +99,7 @@ end it 'passes security properties to the release', - app_fixture: 'container_tomcat_geode_store', + app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store.tar' do component.release @@ -120,18 +120,18 @@ 'credentials' => { 'locators' => ['some-locator[some-port]', 'some-other-locator[some-other-port]'], 'users' => - [ - { - 'password' => 'some-password', - 'username' => 'cluster_operator' - } - ] + [ + { + 'password' => 'some-password', + 'username' => 'cluster_operator' + } + ] } ) end it 'assumes usernames represent roles and passes security properties to the release', - app_fixture: 'container_tomcat_geode_store', + app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store.tar' do component.release diff --git a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb index 01c6b20bc5..48e280659f 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb @@ -39,7 +39,7 @@ end it 'extracts Tomcat from a GZipped TAR', - app_fixture: 'container_tomcat', + app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat.tar.gz' do component.compile @@ -50,7 +50,7 @@ end it 'configures for Tomcat 7', - app_fixture: 'container_tomcat', + app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat.tar.gz' do component.compile @@ -63,7 +63,7 @@ let(:version) { '8.0.12' } it 'configures for Tomcat 8', - app_fixture: 'container_tomcat', + app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat.tar.gz' do component.compile @@ -74,7 +74,7 @@ end it 'links only the application files and directories to the ROOT webapp', - app_fixture: 'container_tomcat_with_index', + app_fixture: 'container_tomcat_with_index', cache_fixture: 'stub-tomcat.tar.gz' do FileUtils.touch(app_dir + '.test-file') @@ -100,7 +100,7 @@ let(:configuration) { { 'context_path' => '/first-segment/second-segment' } } it 'links only the application files and directories to the first-segment#second-segment webapp', - app_fixture: 'container_tomcat_with_index', + app_fixture: 'container_tomcat_with_index', cache_fixture: 'stub-tomcat.tar.gz' do FileUtils.touch(app_dir + '.test-file') @@ -124,20 +124,20 @@ end it 'links the Tomcat datasource JAR to the ROOT webapp when that JAR is present', - app_fixture: 'container_tomcat', + app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat7.tar.gz' do component.compile web_inf_lib = app_dir + 'WEB-INF/lib' - app_jar = web_inf_lib + 'tomcat-jdbc.jar' + app_jar = web_inf_lib + 'tomcat-jdbc.jar' expect(app_jar).to exist expect(app_jar).to be_symlink expect(app_jar.readlink).to eq((sandbox + 'lib/tomcat-jdbc.jar').relative_path_from(web_inf_lib)) end it 'does not link the Tomcat datasource JAR to the ROOT webapp when that JAR is absent', - app_fixture: 'container_tomcat', + app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat.tar.gz' do component.compile @@ -147,7 +147,7 @@ end it 'links additional libraries to the ROOT webapp', - app_fixture: 'container_tomcat', + app_fixture: 'container_tomcat', cache_fixture: 'stub-tomcat.tar.gz' do component.compile diff --git a/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb index dc256fb8dc..5d8a0017fb 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb @@ -25,8 +25,8 @@ let(:component_id) { 'tomcat' } let(:configuration) do - { 'database' => 'test-database', - 'timeout' => 'test-timeout', + { 'database' => 'test-database', + 'timeout' => 'test-timeout', 'connection_pool_size' => 'test-connection-pool-size' } end @@ -40,7 +40,7 @@ allow(services).to receive(:one_service?).with(/session-replication/, %w[hostname host], 'port', 'password') .and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'hostname' => 'test-host', - 'port' => 'test-port', + 'port' => 'test-port', 'password' => 'test-password' }) end @@ -49,7 +49,7 @@ end it 'copies resources', - app_fixture: 'container_tomcat_redis_store', + app_fixture: 'container_tomcat_redis_store', cache_fixture: 'stub-redis-store.jar' do component.compile @@ -58,7 +58,7 @@ end it 'mutates context.xml', - app_fixture: 'container_tomcat_redis_store', + app_fixture: 'container_tomcat_redis_store', cache_fixture: 'stub-redis-store.jar' do component.compile @@ -74,8 +74,8 @@ before do allow(services).to receive(:one_service?).with(/session-replication/, %w[hostname host], 'port', 'password') .and_return(true) - allow(services).to receive(:find_service).and_return('credentials' => { 'host' => 'test-host', - 'port' => 'test-port', + allow(services).to receive(:find_service).and_return('credentials' => { 'host' => 'test-host', + 'port' => 'test-port', 'password' => 'test-password' }) end diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index 1b45e64909..32a2ec5032 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -35,11 +35,11 @@ let(:configuration) do { 'access_logging_support' => access_logging_support_configuration, 'external_configuration' => tomcat_external_configuration, - 'geode_store' => geode_store_configuration, - 'lifecycle_support' => lifecycle_support_configuration, - 'logging_support' => logging_support_configuration, - 'redis_store' => redis_store_configuration, - 'tomcat' => tomcat_configuration } + 'geode_store' => geode_store_configuration, + 'lifecycle_support' => lifecycle_support_configuration, + 'logging_support' => logging_support_configuration, + 'redis_store' => redis_store_configuration, + 'tomcat' => tomcat_configuration } end let(:access_logging_support_configuration) { instance_double('logging-support-configuration') } @@ -119,7 +119,7 @@ class StubTomcat < JavaBuildpack::Container::Tomcat end def sub_configuration_context(configuration) - c = context.clone + c = context.clone c[:configuration] = configuration c end diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 41b1128490..a1f88852cb 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -23,8 +23,8 @@ include_context 'with component help' let(:configuration) do - { 'default_tier_name' => nil, - 'default_node_name' => "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')", + { 'default_tier_name' => nil, + 'default_node_name' => "$(expr \"$VCAP_APPLICATION\" : '.*instance_index[\": ]*\\([[:digit:]]*\\).*')", 'default_application_name' => nil } end diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb index 11e17b0370..d7a3287a80 100644 --- a/spec/java_buildpack/framework/contrast_security_agent_spec.rb +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -33,9 +33,9 @@ allow(services).to receive(:one_service?).with(/contrast-security/, 'api_key', 'service_key', 'teamserver_url', 'username').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'teamserver_url' => 'a_url', - 'username' => 'contrast_user', - 'api_key' => 'api_test', - 'service_key' => 'service_test' }) + 'username' => 'contrast_user', + 'api_key' => 'api_test', + 'service_key' => 'service_test' }) end it 'detects with contrastsecurity service' do diff --git a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb index d3262096fa..4f9bbe6f74 100644 --- a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb +++ b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb @@ -35,12 +35,12 @@ allow(services).to receive(:find_service).and_return( 'credentials' => { - 'ca' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", - 'key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----", + 'ca' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", + 'key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----", 'recv_timeout' => 1, - 'retries' => 2, + 'retries' => 2, 'send_timeout' => 3, - 'servers' => 'server-1,server-2' + 'servers' => 'server-1,server-2' } ) end @@ -105,8 +105,8 @@ context do let(:java_home_delegate) do - delegate = JavaBuildpack::Component::MutableJavaHome.new - delegate.root = app_dir + '.test-java-home' + delegate = JavaBuildpack::Component::MutableJavaHome.new + delegate.root = app_dir + '.test-java-home' delegate.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') delegate diff --git a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb index 94658bc919..78cc79cec5 100644 --- a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb @@ -74,7 +74,7 @@ allow(services).to receive(:one_service?).with(/dynatrace/, 'server').and_return(true) allow(services).to receive(:one_service?).with(/dynatrace/, 'tenant').and_return(false) allow(services).to receive(:one_service?).with(/dynatrace/, 'tenanttoken').and_return(false) - allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name', + allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name', 'profile' => 'test-profile' }) end diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index c21d60b044..91088d3bb3 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -32,8 +32,8 @@ before do allow(services).to receive(:one_service?).with(/dynatrace/, 'apitoken', 'environmentid').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-environmentid', - 'apiurl' => 'test-apiurl', - 'apitoken' => 'test-apitoken' }) + 'apiurl' => 'test-apiurl', + 'apitoken' => 'test-apitoken' }) allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&' \ @@ -96,8 +96,8 @@ before do allow(services).to receive(:one_service?).with(/dynatrace/, 'apitoken', 'environmentid').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-environmentid', - 'apiurl' => 'test-apiurl', - 'apitoken' => 'test-apitoken' }) + 'apiurl' => 'test-apiurl', + 'apitoken' => 'test-apitoken' }) allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64' \ '&Api-Token=test-apitoken') @@ -115,9 +115,9 @@ before do allow(services).to receive(:one_service?).with(/dynatrace/, 'apitoken', 'environmentid').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-environmentid', - 'apiurl' => 'test-apiurl', - 'apitoken' => 'test-apitoken', - 'skiperrors' => 'true' }) + 'apiurl' => 'test-apiurl', + 'apitoken' => 'test-apitoken', + 'skiperrors' => 'true' }) allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64' \ '&Api-Token=test-apitoken') diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index 3d78786422..6d2f4e9b11 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -277,7 +277,7 @@ context do let(:credentials) do - { 'agent_manager_url' => 'https://test-host-name:8444', + { 'agent_manager_url' => 'https://test-host-name:8444', 'agent_manager_credential' => 'test-credential-cccf-88-ae' } end @@ -304,7 +304,7 @@ context do let(:credentials) do - { 'agent_manager_url' => 'https://test-host-name:8444', + { 'agent_manager_url' => 'https://test-host-name:8444', 'agent_manager_credential' => 'test-credential-cccf-88-ae', 'agent_default_process_name' => 'TestProcess' } end diff --git a/spec/java_buildpack/framework/jacoco_agent_spec.rb b/spec/java_buildpack/framework/jacoco_agent_spec.rb index a6ae91f411..7481969ce3 100644 --- a/spec/java_buildpack/framework/jacoco_agent_spec.rb +++ b/spec/java_buildpack/framework/jacoco_agent_spec.rb @@ -55,10 +55,10 @@ end it 'updates JAVA_OPTS with additional options' do - allow(services).to receive(:find_service).and_return('credentials' => { 'address' => 'test-address', + allow(services).to receive(:find_service).and_return('credentials' => { 'address' => 'test-address', 'excludes' => 'test-excludes', 'includes' => 'test-includes', - 'port' => 6300 }) + 'port' => 6300 }) component.release diff --git a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb index b712128a70..d2c5cbab9f 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb @@ -88,7 +88,7 @@ [ { 'container_dir' => '/my_volume', - 'mode' => 'rw' + 'mode' => 'rw' } ]) end @@ -118,13 +118,13 @@ [ { 'container_dir' => '/my_volume', - 'mode' => 'r' + 'mode' => 'r' } ]) end it 'fails if volume does not have write mode active', :enable_log_file, log_level: 'DEBUG' do - expect { component.release } .to raise_error 'Volume mounted under \'/my_volume\' not in write mode' + expect { component.release }.to raise_error 'Volume mounted under \'/my_volume\' not in write mode' expect(log_contents).not_to match(/Heap dumps will be stored under/) end diff --git a/spec/java_buildpack/framework/java_memory_assistant_spec.rb b/spec/java_buildpack/framework/java_memory_assistant_spec.rb index d09b428d31..ceaf6756a8 100644 --- a/spec/java_buildpack/framework/java_memory_assistant_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant_spec.rb @@ -45,9 +45,9 @@ context do let(:configuration) do - { 'enabled' => true, - 'agent' => agent_configuration, - 'clean_up' => clean_up_configuration } + { 'enabled' => true, + 'agent' => agent_configuration, + 'clean_up' => clean_up_configuration } end let(:agent_configuration) { instance_double('agent_configuration') } diff --git a/spec/java_buildpack/framework/jrebel_agent_spec.rb b/spec/java_buildpack/framework/jrebel_agent_spec.rb index 512e55426e..8da64b05cc 100644 --- a/spec/java_buildpack/framework/jrebel_agent_spec.rb +++ b/spec/java_buildpack/framework/jrebel_agent_spec.rb @@ -55,7 +55,7 @@ end it 'downloads the JRebel JAR and the native agent', - app_fixture: 'framework_jrebel_app_simple', + app_fixture: 'framework_jrebel_app_simple', cache_fixture: 'stub-jrebel-archive.zip' do component.compile @@ -65,7 +65,7 @@ end it 'adds correct arguments to JAVA_OPTS', - app_fixture: 'framework_jrebel_app_simple', + app_fixture: 'framework_jrebel_app_simple', cache_fixture: 'stub-jrebel-archive.zip' do allow(component).to receive(:architecture).and_return('x86_64') diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index a857a56ffb..475fb58ffc 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -39,19 +39,19 @@ }, 'servers' => [ { - 'name' => 'test-server-1', + 'name' => 'test-server-1', 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-1-cert\n-----END CERTIFICATE-----" }, { - 'name' => 'test-server-2', + 'name' => 'test-server-2', 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-2-cert\n-----END CERTIFICATE-----" } ], 'groups' => [ { - 'label' => 'test-group-1', + 'label' => 'test-group-1', 'members' => %w[test-group-1-member-1 test-group-1-member-2] }, { - 'label' => 'test-group-2', + 'label' => 'test-group-2', 'members' => %w[test-group-2-member-1 test-group-2-member-2] } ] @@ -129,8 +129,8 @@ context do let(:java_home_delegate) do - delegate = JavaBuildpack::Component::MutableJavaHome.new - delegate.root = app_dir + '.test-java-home' + delegate = JavaBuildpack::Component::MutableJavaHome.new + delegate.root = app_dir + '.test-java-home' delegate.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') delegate @@ -161,8 +161,8 @@ context do let(:configuration) do { - 'logging_enabled' => true, - 'ha_logging_enabled' => true, + 'logging_enabled' => true, + 'ha_logging_enabled' => true, 'tcp_keep_alive_enabled' => false } end @@ -181,8 +181,8 @@ context do let(:configuration) do { - 'logging_enabled' => true, - 'ha_logging_enabled' => true, + 'logging_enabled' => true, + 'ha_logging_enabled' => true, 'tcp_keep_alive_enabled' => true } end diff --git a/spec/java_buildpack/framework/metric_writer_spec.rb b/spec/java_buildpack/framework/metric_writer_spec.rb index 3c911e2a66..2a00934f46 100644 --- a/spec/java_buildpack/framework/metric_writer_spec.rb +++ b/spec/java_buildpack/framework/metric_writer_spec.rb @@ -56,7 +56,7 @@ cache_fixture: 'stub-metric-writer.jar' do allow(services).to receive(:find_service).and_return('credentials' => { 'access_key' => 'test-access-key', - 'endpoint' => 'https://test-endpoint' }) + 'endpoint' => 'https://test-endpoint' }) component.release @@ -65,7 +65,7 @@ it 'updates JAVA_OPTS' do allow(services).to receive(:find_service).and_return('credentials' => { 'access_key' => 'test-access-key', - 'endpoint' => 'https://test-endpoint' }) + 'endpoint' => 'https://test-endpoint' }) component.release diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index cf7ff2dfdf..79341e48eb 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -51,7 +51,7 @@ end it 'downloads additional libraries', - app_fixture: 'framework_auto_reconfiguration_servlet_3', + app_fixture: 'framework_auto_reconfiguration_servlet_3', cache_fixture: 'stub-auto-reconfiguration.jar' do component.compile @@ -60,7 +60,7 @@ end it 'adds to additional libraries', - app_fixture: 'framework_auto_reconfiguration_servlet_3', + app_fixture: 'framework_auto_reconfiguration_servlet_3', cache_fixture: 'stub-auto-reconfiguration.jar' do component.release diff --git a/spec/java_buildpack/framework/spring_insight_spec.rb b/spec/java_buildpack/framework/spring_insight_spec.rb index 1d97ca2bbc..d899130f93 100644 --- a/spec/java_buildpack/framework/spring_insight_spec.rb +++ b/spec/java_buildpack/framework/spring_insight_spec.rb @@ -35,12 +35,12 @@ allow(services).to receive(:one_service?) .with(/p-insight/, 'agent_download_url', 'service_instance_id').and_return(true) allow(services).to receive(:find_service).and_return( - 'label' => 'p-insight', + 'label' => 'p-insight', 'credentials' => { - 'version' => '2.0.0', - 'agent_download_url' => 'test-uri/services/config/agent-download', - 'agent_password' => 'foo', - 'agent_username' => 'bar', + 'version' => '2.0.0', + 'agent_download_url' => 'test-uri/services/config/agent-download', + 'agent_password' => 'foo', + 'agent_username' => 'bar', 'service_instance_id' => '12345' } ) @@ -88,14 +88,14 @@ allow(services).to receive(:one_service?) .with(/p-insight/, 'agent_download_url', 'service_instance_id').and_return(true) allow(services).to receive(:find_service).and_return( - 'label' => 'p-insight', + 'label' => 'p-insight', 'credentials' => { - 'version' => '2.0.0', - 'agent_download_url' => 'test-uri/services/config/agent-download', - 'agent_password' => 'foo', - 'agent_username' => 'bar', + 'version' => '2.0.0', + 'agent_download_url' => 'test-uri/services/config/agent-download', + 'agent_password' => 'foo', + 'agent_username' => 'bar', 'service_instance_id' => '12345', - 'agent_transport' => 'activemq' + 'agent_transport' => 'activemq' } ) allow(application_cache).to receive(:get) diff --git a/spec/java_buildpack/jre/ibm_jre_spec.rb b/spec/java_buildpack/jre/ibm_jre_spec.rb index 88c43f5754..a11ede0cb9 100644 --- a/spec/java_buildpack/jre/ibm_jre_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_spec.rb @@ -30,7 +30,7 @@ let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } let(:configuration) do - { 'jre' => jre_configuration, + { 'jre' => jre_configuration, 'jvmkill_agent' => jvmkill_agent_configuration } end @@ -66,7 +66,7 @@ def supports? end def sub_configuration_context(configuration) - cntxt = context.clone + cntxt = context.clone cntxt[:configuration] = configuration cntxt end diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 6deb03b4dd..fda9413d59 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -97,7 +97,7 @@ end it 'does not throw an error when a directory ends in .jar', - app_fixture: 'jre_memory_calculator_jar_directory', + app_fixture: 'jre_memory_calculator_jar_directory', cache_fixture: 'stub-memory-calculator.tar.gz' do expect_any_instance_of(described_class).not_to receive(:`).with(start_with("unzip -l #{app_dir + 'directory.jar'}")) diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index 002fb46905..4acb6d02d1 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -36,9 +36,9 @@ let(:version_8) { VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } let(:configuration) do - { 'jre' => jre_configuration, + { 'jre' => jre_configuration, 'memory_calculator' => memory_calculator_configuration, - 'jvmkill_agent' => jvmkill_agent_configuration } + 'jvmkill_agent' => jvmkill_agent_configuration } end let(:jre_configuration) { instance_double('jre_configuration') } @@ -99,7 +99,7 @@ def supports? end def sub_configuration_context(configuration) - c = context.clone + c = context.clone c[:configuration] = configuration c end diff --git a/spec/java_buildpack/repository/configured_item_spec.rb b/spec/java_buildpack/repository/configured_item_spec.rb index 2eaf4ff4a6..b1bb6f1419 100644 --- a/spec/java_buildpack/repository/configured_item_spec.rb +++ b/spec/java_buildpack/repository/configured_item_spec.rb @@ -38,9 +38,9 @@ it 'resolves a system.properties version if specified' do details = described_class.find_item('Test', - 'repository_root' => 'test-repository-root', + 'repository_root' => 'test-repository-root', 'java.runtime.version' => 'test-java-runtime-version', - 'version' => '1.7.0') + 'version' => '1.7.0') expect(details[0]).to eq(resolved_version) expect(details[1]).to eq(resolved_uri) @@ -49,7 +49,7 @@ it 'resolves a configuration version if specified' do details = described_class.find_item('Test', 'repository_root' => 'test-repository-root', - 'version' => '1.7.0') + 'version' => '1.7.0') expect(details[0]).to eq(resolved_version) expect(details[1]).to eq(resolved_uri) @@ -58,7 +58,7 @@ it 'drives the version validator block if supplied' do described_class.find_item('Test', 'repository_root' => 'test-repository-root', - 'version' => '1.7.0') do |version| + 'version' => '1.7.0') do |version| expect(version).to eq(JavaBuildpack::Util::TokenizedVersion.new('1.7.0')) end end diff --git a/spec/java_buildpack/util/cache/application_cache_spec.rb b/spec/java_buildpack/util/cache/application_cache_spec.rb index e0c7ef6211..593bd25e0a 100644 --- a/spec/java_buildpack/util/cache/application_cache_spec.rb +++ b/spec/java_buildpack/util/cache/application_cache_spec.rb @@ -36,7 +36,7 @@ .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) stub_request(:head, 'http://foo-uri/') - .with(headers: { 'Accept' => '*/*', 'If-Modified-Since' => 'foo-last-modified', 'If-None-Match' => 'foo-etag', + .with(headers: { 'Accept' => '*/*', 'If-Modified-Since' => 'foo-last-modified', 'If-None-Match' => 'foo-etag', 'User-Agent' => 'Ruby' }) .to_return(status: 304, body: '', headers: {}) end @@ -46,7 +46,7 @@ end it 'raises an error if ARGV[1] is not defined' do - expect { described_class.new }.to raise_error + expect { described_class.new }.to raise_error RuntimeError end it 'uses ARGV[1] directory' do diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 2261edcaa9..e63ca2999d 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -42,7 +42,7 @@ let(:uri_secure) { 'https://foo-uri/' } let(:download_cache) do - download_cache = described_class.new(mutable_cache_root, immutable_cache_root) + download_cache = described_class.new(mutable_cache_root, immutable_cache_root) download_cache.retry_max = 0 download_cache end @@ -168,8 +168,8 @@ it 'discards content with incorrect size' do stub_request(:get, uri) - .to_return(status: 200, body: 'foo-cac', headers: { Etag: 'foo-etag', - 'Last-Modified' => 'foo-last-modified', + .to_return(status: 200, body: 'foo-cac', headers: { Etag: 'foo-etag', + 'Last-Modified' => 'foo-last-modified', 'Content-Length' => 10 }) touch immutable_cache_root, 'cached', 'old-foo-cached' @@ -179,10 +179,10 @@ it 'ignores incorrect size when encoded' do stub_request(:get, uri) - .to_return(status: 200, body: 'foo-cac', headers: { Etag: 'foo-etag', + .to_return(status: 200, body: 'foo-cac', headers: { Etag: 'foo-etag', 'Content-Encoding' => 'gzip', - 'Last-Modified' => 'foo-last-modified', - 'Content-Length' => 10 }) + 'Last-Modified' => 'foo-last-modified', + 'Content-Length' => 10 }) touch immutable_cache_root, 'cached', 'old-foo-cached' @@ -195,7 +195,7 @@ it 'uses http_proxy if specified' do stub_request(:get, uri) - .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', + .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original @@ -212,7 +212,7 @@ it 'uses HTTP_PROXY if specified' do stub_request(:get, uri) - .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', + .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original @@ -229,7 +229,7 @@ it 'uses https_proxy if specified and URL is secure' do stub_request(:get, uri_secure) - .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', + .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original @@ -246,7 +246,7 @@ it 'uses HTTPS_PROXY if specified and URL is secure' do stub_request(:get, uri_secure) - .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', + .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original @@ -262,7 +262,7 @@ it 'does not use proxy if host in NO_PROXY' do stub_request(:get, uri_secure) - .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', + .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original @@ -278,7 +278,7 @@ it 'does not use proxy if host in no_proxy' do stub_request(:get, uri_secure) - .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', + .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index a7075060c7..fa22a0f776 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -27,9 +27,9 @@ include_context 'with logging help' let(:test_data) do - { 'foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, - 'version' => '1.7.1', + { 'foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.7.1', 'not_here' => nil } end @@ -42,9 +42,9 @@ end it 'write configuration file' do - test_file = Pathname.new(File.expand_path('../../../config/open_jdk_jre.yml', File.dirname(__FILE__))) + test_file = Pathname.new(File.expand_path('../../../config/open_jdk_jre.yml', File.dirname(__FILE__))) original_content = file_contents test_file - loaded_content = described_class.load('open_jdk_jre', false) + loaded_content = described_class.load('open_jdk_jre', false) described_class.write('open_jdk_jre', loaded_content) expect(described_class.load('open_jdk_jre', false)).to eq(loaded_content) expect(file_contents(test_file)).to eq(original_content) @@ -65,8 +65,8 @@ end it 'load configuration file and clean nil values' do - expect(described_class.load('test', true)).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + expect(described_class.load('test', true)).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, 'version' => '1.7.1') end @@ -78,8 +78,8 @@ it 'overlays matching environment variables' do - expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 3, 'two' => 'dog' } }, + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 3, 'two' => 'dog' } }, 'version' => '1.7.1') end @@ -92,8 +92,8 @@ end it 'overlays simple matching environment variable' do - expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, - 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, 'version' => '1.8.+') end diff --git a/spec/java_buildpack/util/shell_spec.rb b/spec/java_buildpack/util/shell_spec.rb index 8a80727dc8..11859f0d23 100644 --- a/spec/java_buildpack/util/shell_spec.rb +++ b/spec/java_buildpack/util/shell_spec.rb @@ -29,7 +29,7 @@ end it 'raises an error if command returns a non-zero exit code' do - expect { shell 'false' }.to raise_error + expect { shell 'false' }.to raise_error RuntimeError end it 'handles a large amount of output' do diff --git a/spec/java_buildpack/util/spring_boot_utils_spec.rb b/spec/java_buildpack/util/spring_boot_utils_spec.rb index 77824278ea..e164b15048 100644 --- a/spec/java_buildpack/util/spring_boot_utils_spec.rb +++ b/spec/java_buildpack/util/spring_boot_utils_spec.rb @@ -99,7 +99,7 @@ end it 'fails if there are no lib directories' do - expect { utils.lib(droplet) }.to raise_error + expect { utils.lib(droplet) }.to raise_error RuntimeError end it 'caches thin dependencies' do From 4d4c5620b5c995cc8f0c7dbb169496ce18bcaa64 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Jan 2019 15:43:15 -0800 Subject: [PATCH 465/812] Polishing Signed-off-by: Ben Hale --- spec/java_buildpack/component/modular_component_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/java_buildpack/component/modular_component_spec.rb b/spec/java_buildpack/component/modular_component_spec.rb index d7d0a2f7ea..5a4742e17d 100644 --- a/spec/java_buildpack/component/modular_component_spec.rb +++ b/spec/java_buildpack/component/modular_component_spec.rb @@ -39,8 +39,8 @@ end it 'fails if methods are unimplemented' do - expect { component.command }.to raise_error RuntimeError - expect { component.sub_components(context) }.to raise_error RuntimeError + expect { component.command }.to raise_error NoMethodError + expect { component.sub_components(context) }.to raise_error NoMethodError end end From d0c84315238388555173bf7d2d51f7b0ae29c805 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Jan 2019 16:14:20 -0800 Subject: [PATCH 466/812] Revert API that does not exist in 2.3 Signed-off-by: Ben Hale --- .idea/misc.xml | 2 +- .idea/runConfigurations/rubocop.xml | 11 ++-- .idea/runConfigurations/versions.xml | 11 ++-- .../runConfigurations/versions__Markdown_.xml | 11 ++-- .../versions__Pivotal_Network_.xml | 11 ++-- .idea/runConfigurations/versions__YAML_.xml | 11 ++-- .ruby-version | 2 +- ci/docker-image/Dockerfile | 3 + java-buildpack.iml | 60 +++++++++---------- lib/java_buildpack/container/dist_zip_like.rb | 4 +- .../jre/open_jdk_like_memory_calculator.rb | 2 +- .../repository/repository_index.rb | 2 +- rakelib/dependency_cache_task.rb | 2 +- rakelib/versions_task.rb | 2 +- 14 files changed, 71 insertions(+), 63 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index e87ee0f57d..61a60b2e60 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,5 +4,5 @@ - + \ No newline at end of file diff --git a/.idea/runConfigurations/rubocop.xml b/.idea/runConfigurations/rubocop.xml index d363b94a8f..e6ac5bd81b 100644 --- a/.idea/runConfigurations/rubocop.xml +++ b/.idea/runConfigurations/rubocop.xml @@ -1,15 +1,14 @@ - + - + - - + @@ -20,6 +19,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/versions.xml b/.idea/runConfigurations/versions.xml index 31c0dbcaa5..419c96cf97 100644 --- a/.idea/runConfigurations/versions.xml +++ b/.idea/runConfigurations/versions.xml @@ -1,15 +1,14 @@ - + - + - - + @@ -20,6 +19,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/versions__Markdown_.xml b/.idea/runConfigurations/versions__Markdown_.xml index 6b7ebbb7d2..98c17ad2ba 100644 --- a/.idea/runConfigurations/versions__Markdown_.xml +++ b/.idea/runConfigurations/versions__Markdown_.xml @@ -1,15 +1,14 @@ - + - + - - + @@ -20,6 +19,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/versions__Pivotal_Network_.xml b/.idea/runConfigurations/versions__Pivotal_Network_.xml index 055e603872..5139f49ed7 100644 --- a/.idea/runConfigurations/versions__Pivotal_Network_.xml +++ b/.idea/runConfigurations/versions__Pivotal_Network_.xml @@ -1,15 +1,14 @@ - + - + - - + @@ -20,6 +19,8 @@ - + + \ No newline at end of file diff --git a/.idea/runConfigurations/versions__YAML_.xml b/.idea/runConfigurations/versions__YAML_.xml index 0dd45fc663..4c2a1a108c 100644 --- a/.idea/runConfigurations/versions__YAML_.xml +++ b/.idea/runConfigurations/versions__YAML_.xml @@ -1,15 +1,14 @@ - + - + - - + @@ -20,6 +19,8 @@ - + + \ No newline at end of file diff --git a/.ruby-version b/.ruby-version index 59aa62c1fa..bc4abe86de 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4.5 +2.3.8 diff --git a/ci/docker-image/Dockerfile b/ci/docker-image/Dockerfile index 05a4cb533e..ca6e71f8ef 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/docker-image/Dockerfile @@ -29,6 +29,9 @@ RUN eval "$(rbenv init -)" \ && git clone https://github.com/sstephenson/rbenv-default-gems.git $(rbenv root)/plugins/rbenv-default-gems \ && echo 'bundler' >> $(rbenv root)/default-gems +RUN eval "$(rbenv init -)" \ + && rbenv install 2.3.8 + RUN eval "$(rbenv init -)" \ && rbenv install 2.4.5 diff --git a/java-buildpack.iml b/java-buildpack.iml index 2b92fdf531..21cffc3218 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -265,37 +265,37 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index a1aeb685be..60f9a0aae6 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -103,9 +103,9 @@ def augment_classpath(content) def augment_classpath_content content = start_script(root).read - if content.match? PATTERN_CLASSPATH + if content =~ PATTERN_CLASSPATH augment_classpath content - elsif content.match? PATTERN_APP_CLASSPATH + elsif content =~ PATTERN_APP_CLASSPATH augment_app_classpath content end end diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 0b20ca9a0c..9d7618e556 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -98,7 +98,7 @@ def memory_calculator end def memory_calculator_tar - platform = `uname -s`.match?(/Darwin/) ? 'darwin' : 'linux' + platform = `uname -s` =~ /Darwin/ ? 'darwin' : 'linux' @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{platform}" end diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 81364b1cca..84298e7587 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -87,7 +87,7 @@ def platform if redhat_release.exist? tokens = redhat_release.read.match(/(\w+) (?:Linux )?release (\d+)/) "#{tokens[1].downcase}#{tokens[2]}" - elsif `uname -s`.match?(/Darwin/) + elsif `uname -s` =~ /Darwin/ 'mountainlion' elsif !`which lsb_release 2> /dev/null`.empty? `lsb_release -cs`.strip diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 056fc82492..2a577d4af3 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -59,7 +59,7 @@ def initialize def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at raw.map(&block) - elsif raw[:uri].match? pattern + elsif raw[:uri] =~ pattern candidates.map do |candidate| dup = raw.clone dup[key] = candidate diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index d0d21203a0..20dfcfff55 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -101,7 +101,7 @@ def initialize def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at raw.map(&block) - elsif raw[:uri].match? pattern + elsif raw[:uri] =~ pattern candidates.map do |candidate| dup = raw.clone dup[key] = candidate From c73ee1b5e5b23f3cbadce6ded2564293b8b96548 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 7 Jan 2019 16:18:08 -0800 Subject: [PATCH 467/812] Test Configuration Signed-off-by: Ben Hale --- .idea/runConfigurations/All_Tests__2_3_.xml | 38 +++++++++++++++++++ .../Without_Integration_Tests__2_3_.xml | 38 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 .idea/runConfigurations/All_Tests__2_3_.xml create mode 100644 .idea/runConfigurations/Without_Integration_Tests__2_3_.xml diff --git a/.idea/runConfigurations/All_Tests__2_3_.xml b/.idea/runConfigurations/All_Tests__2_3_.xml new file mode 100644 index 0000000000..1dad940286 --- /dev/null +++ b/.idea/runConfigurations/All_Tests__2_3_.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml new file mode 100644 index 0000000000..d7632a26c4 --- /dev/null +++ b/.idea/runConfigurations/Without_Integration_Tests__2_3_.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From f4744156d891cbb3e36c1659d3e8a5e32fde82e0 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 8 Jan 2019 09:20:37 -0800 Subject: [PATCH 468/812] Stabilize tests Signed-off-by: Ben Hale --- .../component/modular_component_spec.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/spec/java_buildpack/component/modular_component_spec.rb b/spec/java_buildpack/component/modular_component_spec.rb index 5a4742e17d..aab2f4c40f 100644 --- a/spec/java_buildpack/component/modular_component_spec.rb +++ b/spec/java_buildpack/component/modular_component_spec.rb @@ -39,8 +39,8 @@ end it 'fails if methods are unimplemented' do - expect { component.command }.to raise_error NoMethodError - expect { component.sub_components(context) }.to raise_error NoMethodError + expect { component.command }.to raise_error RuntimeError + expect { component.sub_components(context) }.to raise_error RuntimeError end end @@ -80,6 +80,16 @@ class StubModularComponent < JavaBuildpack::Component::ModularComponent - public :command, :sub_components, :supports? + def command + super + end + + def sub_components(_context) + super _context + end + + def supports? + super + end end From 94c8acd2a1c765c1c07be336d6f1f41373535183 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 8 Jan 2019 09:23:15 -0800 Subject: [PATCH 469/812] Polishing Signed-off-by: Ben Hale --- spec/java_buildpack/component/modular_component_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/java_buildpack/component/modular_component_spec.rb b/spec/java_buildpack/component/modular_component_spec.rb index aab2f4c40f..b079dfa120 100644 --- a/spec/java_buildpack/component/modular_component_spec.rb +++ b/spec/java_buildpack/component/modular_component_spec.rb @@ -84,8 +84,8 @@ def command super end - def sub_components(_context) - super _context + def sub_components(context) + super context end def supports? From c8568b409d6b044805b62a75984f242247a25047 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 8 Jan 2019 09:41:39 -0800 Subject: [PATCH 470/812] Copyright Updates Signed-off-by: Ben Hale --- Rakefile | 2 +- bin/compile | 2 +- bin/detect | 2 +- bin/finalize | 2 +- bin/release | 2 +- ci/auto-merge.sh | 2 +- ci/auto-merge.yml | 2 +- ci/package-test.sh | 2 +- ci/package-test.yml | 2 +- ci/unit-test.sh | 2 +- ci/unit-test.yml | 2 +- ci/versions-json.sh | 2 +- ci/versions-json.yml | 2 +- ci/versions-markdown.sh | 2 +- ci/versions-markdown.yml | 2 +- ci/versions-yaml.sh | 2 +- ci/versions-yaml.yml | 2 +- ci/versions.sh | 2 +- ci/versions.yml | 2 +- config/app_dynamics_agent.yml | 2 +- config/aspectj_weaver_agent.yml | 2 +- config/azure_application_insights_agent.yml | 2 +- config/cache.yml | 2 +- config/client_certificate_mapper.yml | 2 +- config/components.yml | 2 +- config/container_customizer.yml | 2 +- config/container_security_provider.yml | 2 +- config/contrast_security_agent.yml | 2 +- config/debug.yml | 2 +- config/dyadic_ekm_security_provider.yml | 2 +- config/dynatrace_appmon_agent.yml | 2 +- config/dynatrace_one_agent.yml | 2 +- config/google_stackdriver_debugger.yml | 2 +- config/google_stackdriver_profiler.yml | 2 +- config/groovy.yml | 2 +- config/introscope_agent.yml | 2 +- config/java_main.yml | 2 +- config/java_memory_assistant.yml | 2 +- config/java_opts.yml | 2 +- config/jmx.yml | 2 +- config/jprofiler_profiler.yml | 2 +- config/jrebel_agent.yml | 2 +- config/logging.yml | 2 +- config/luna_security_provider.yml | 2 +- config/maria_db_jdbc.yml | 2 +- config/metric_writer.yml | 2 +- config/new_relic_agent.yml | 2 +- config/open_jdk_jre.yml | 2 +- config/oracle_jre.yml | 2 +- config/postgresql_jdbc.yml | 2 +- config/repository.yml | 2 +- config/riverbed_appinternals_agent.yml | 2 +- config/sky_walking_agent.yml | 2 +- config/spring_auto_reconfiguration.yml | 2 +- config/spring_boot_cli.yml | 2 +- config/takipi_agent.yml | 2 +- config/tomcat.yml | 2 +- config/your_kit_profiler.yml | 2 +- config/zulu_jre.yml | 2 +- lib/java_buildpack.rb | 2 +- lib/java_buildpack/buildpack.rb | 2 +- lib/java_buildpack/buildpack_version.rb | 2 +- lib/java_buildpack/component.rb | 2 +- lib/java_buildpack/component/additional_libraries.rb | 2 +- lib/java_buildpack/component/application.rb | 2 +- lib/java_buildpack/component/base_component.rb | 2 +- lib/java_buildpack/component/droplet.rb | 2 +- lib/java_buildpack/component/environment_variables.rb | 2 +- lib/java_buildpack/component/extension_directories.rb | 2 +- lib/java_buildpack/component/immutable_java_home.rb | 2 +- lib/java_buildpack/component/java_opts.rb | 2 +- lib/java_buildpack/component/modular_component.rb | 2 +- lib/java_buildpack/component/mutable_java_home.rb | 2 +- lib/java_buildpack/component/networking.rb | 2 +- lib/java_buildpack/component/root_libraries.rb | 2 +- lib/java_buildpack/component/security_providers.rb | 2 +- lib/java_buildpack/component/services.rb | 2 +- lib/java_buildpack/component/versioned_dependency_component.rb | 2 +- lib/java_buildpack/container.rb | 2 +- lib/java_buildpack/container/dist_zip.rb | 2 +- lib/java_buildpack/container/dist_zip_like.rb | 2 +- lib/java_buildpack/container/groovy.rb | 2 +- lib/java_buildpack/container/java_main.rb | 2 +- lib/java_buildpack/container/play_framework.rb | 2 +- lib/java_buildpack/container/ratpack.rb | 2 +- lib/java_buildpack/container/spring_boot.rb | 2 +- lib/java_buildpack/container/spring_boot_cli.rb | 2 +- lib/java_buildpack/container/tomcat.rb | 2 +- .../container/tomcat/tomcat_access_logging_support.rb | 2 +- .../container/tomcat/tomcat_external_configuration.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_geode_store.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_insight_support.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_instance.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_logging_support.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_redis_store.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_setenv.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_utils.rb | 2 +- lib/java_buildpack/framework.rb | 2 +- lib/java_buildpack/framework/app_dynamics_agent.rb | 2 +- lib/java_buildpack/framework/aspectj_weaver_agent.rb | 2 +- .../framework/azure_application_insights_agent.rb | 2 +- lib/java_buildpack/framework/client_certificate_mapper.rb | 2 +- lib/java_buildpack/framework/container_customizer.rb | 2 +- lib/java_buildpack/framework/container_security_provider.rb | 2 +- lib/java_buildpack/framework/contrast_security_agent.rb | 2 +- lib/java_buildpack/framework/debug.rb | 2 +- lib/java_buildpack/framework/dyadic_ekm_security_provider.rb | 2 +- lib/java_buildpack/framework/dynatrace_appmon_agent.rb | 2 +- lib/java_buildpack/framework/dynatrace_one_agent.rb | 2 +- lib/java_buildpack/framework/google_stackdriver_debugger.rb | 2 +- lib/java_buildpack/framework/google_stackdriver_profiler.rb | 2 +- lib/java_buildpack/framework/introscope_agent.rb | 2 +- lib/java_buildpack/framework/java_memory_assistant.rb | 2 +- lib/java_buildpack/framework/java_memory_assistant/agent.rb | 2 +- lib/java_buildpack/framework/java_memory_assistant/clean_up.rb | 2 +- .../framework/java_memory_assistant/heap_dump_folder.rb | 2 +- lib/java_buildpack/framework/java_opts.rb | 2 +- lib/java_buildpack/framework/java_security.rb | 2 +- lib/java_buildpack/framework/jmx.rb | 2 +- lib/java_buildpack/framework/jprofiler_profiler.rb | 2 +- lib/java_buildpack/framework/jrebel_agent.rb | 2 +- lib/java_buildpack/framework/luna_security_provider.rb | 2 +- lib/java_buildpack/framework/maria_db_jdbc.rb | 2 +- lib/java_buildpack/framework/metric_writer.rb | 2 +- lib/java_buildpack/framework/multi_buildpack.rb | 2 +- lib/java_buildpack/framework/new_relic_agent.rb | 2 +- lib/java_buildpack/framework/postgresql_jdbc.rb | 2 +- lib/java_buildpack/framework/riverbed_appinternals_agent.rb | 2 +- lib/java_buildpack/framework/sky_walking_agent.rb | 2 +- lib/java_buildpack/framework/spring_auto_reconfiguration.rb | 2 +- lib/java_buildpack/framework/spring_insight.rb | 2 +- lib/java_buildpack/framework/takipi_agent.rb | 2 +- lib/java_buildpack/framework/your_kit_profiler.rb | 2 +- lib/java_buildpack/jre.rb | 2 +- lib/java_buildpack/jre/open_jdk_jre.rb | 2 +- lib/java_buildpack/jre/open_jdk_like.rb | 2 +- lib/java_buildpack/jre/open_jdk_like_jre.rb | 2 +- lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb | 2 +- lib/java_buildpack/jre/open_jdk_like_security_providers.rb | 2 +- lib/java_buildpack/jre/oracle_jre.rb | 2 +- lib/java_buildpack/logging.rb | 2 +- lib/java_buildpack/logging/delegating_logger.rb | 2 +- lib/java_buildpack/logging/logger_factory.rb | 2 +- lib/java_buildpack/repository.rb | 2 +- lib/java_buildpack/repository/configured_item.rb | 2 +- lib/java_buildpack/repository/repository_index.rb | 2 +- lib/java_buildpack/repository/version_resolver.rb | 2 +- lib/java_buildpack/util.rb | 2 +- lib/java_buildpack/util/cache.rb | 2 +- lib/java_buildpack/util/cache/application_cache.rb | 2 +- lib/java_buildpack/util/cache/cache_factory.rb | 2 +- lib/java_buildpack/util/cache/cached_file.rb | 2 +- lib/java_buildpack/util/cache/download_cache.rb | 2 +- lib/java_buildpack/util/cache/inferred_network_failure.rb | 2 +- lib/java_buildpack/util/cache/internet_availability.rb | 2 +- lib/java_buildpack/util/class_file_utils.rb | 2 +- lib/java_buildpack/util/colorize.rb | 2 +- lib/java_buildpack/util/configuration_utils.rb | 2 +- lib/java_buildpack/util/constantize.rb | 2 +- lib/java_buildpack/util/dash_case.rb | 2 +- lib/java_buildpack/util/file_enumerable.rb | 2 +- lib/java_buildpack/util/filtering_pathname.rb | 2 +- lib/java_buildpack/util/find_single_directory.rb | 2 +- lib/java_buildpack/util/format_duration.rb | 2 +- lib/java_buildpack/util/groovy_utils.rb | 2 +- lib/java_buildpack/util/jar_finder.rb | 2 +- lib/java_buildpack/util/java_main_utils.rb | 2 +- lib/java_buildpack/util/play.rb | 2 +- lib/java_buildpack/util/play/base.rb | 2 +- lib/java_buildpack/util/play/factory.rb | 2 +- lib/java_buildpack/util/play/post22.rb | 2 +- lib/java_buildpack/util/play/post22_dist.rb | 2 +- lib/java_buildpack/util/play/post22_staged.rb | 2 +- lib/java_buildpack/util/play/pre22.rb | 2 +- lib/java_buildpack/util/play/pre22_dist.rb | 2 +- lib/java_buildpack/util/play/pre22_staged.rb | 2 +- lib/java_buildpack/util/properties.rb | 2 +- lib/java_buildpack/util/qualify_path.rb | 2 +- lib/java_buildpack/util/ratpack_utils.rb | 2 +- lib/java_buildpack/util/sanitizer.rb | 2 +- lib/java_buildpack/util/shell.rb | 2 +- lib/java_buildpack/util/snake_case.rb | 2 +- lib/java_buildpack/util/space_case.rb | 2 +- lib/java_buildpack/util/spring_boot_utils.rb | 2 +- lib/java_buildpack/util/start_script.rb | 2 +- lib/java_buildpack/util/to_b.rb | 2 +- lib/java_buildpack/util/tokenized_version.rb | 2 +- rakelib/dependency_cache_task.rb | 2 +- rakelib/package.rb | 2 +- rakelib/package_task.rb | 2 +- rakelib/stage_buildpack_task.rb | 2 +- rakelib/versions_task.rb | 2 +- resources/azure_application_insights_agent/AI-Agent.xml | 2 +- resources/tomcat/conf/context.xml | 2 +- resources/tomcat/conf/logging.properties | 2 +- resources/tomcat/conf/server.xml | 2 +- spec/application_helper.rb | 2 +- spec/bin/compile_spec.rb | 2 +- spec/bin/detect_spec.rb | 2 +- spec/bin/release_spec.rb | 2 +- spec/component_helper.rb | 2 +- spec/console_helper.rb | 2 +- spec/droplet_helper.rb | 2 +- spec/fixtures/container_groovy_logback/Alpha.java | 2 +- .../container_groovy_logback/ch/qos/logback/pogo.groovy | 2 +- spec/fixtures/container_groovy_main_method/Alpha.groovy | 2 +- spec/fixtures/container_groovy_main_method/Application.groovy | 2 +- .../fixtures/container_groovy_main_method/directory/Beta.groovy | 2 +- spec/fixtures/container_groovy_non_pogo/Alpha.groovy | 2 +- spec/fixtures/container_groovy_non_pogo/Application.groovy | 2 +- .../container_groovy_non_pogo_with_class_file/logback.groovy | 2 +- spec/fixtures/container_groovy_shebang/Alpha.groovy | 2 +- spec/fixtures/container_groovy_shebang/Application.groovy | 2 +- .../Application.groovy | 2 +- spec/fixtures/container_groovy_with_jars/Application.groovy | 2 +- .../container_ratpack_dist/application-root/app/Ratpack.groovy | 2 +- spec/fixtures/container_ratpack_staged/app/ratpack.groovy | 2 +- .../configuration.groovy | 2 +- .../container_spring_boot_cli_beans_configuration/pogo_1.groovy | 2 +- .../container_spring_boot_cli_groovy_with_web_inf/pogo.groovy | 2 +- spec/fixtures/container_spring_boot_cli_main_method/main.groovy | 2 +- spec/fixtures/container_spring_boot_cli_main_method/pogo.groovy | 2 +- .../fixtures/container_spring_boot_cli_non_pogo/non_pogo.groovy | 2 +- spec/fixtures/container_spring_boot_cli_non_pogo/pogo.groovy | 2 +- .../container_spring_boot_cli_valid_app/directory/pogo_4.groovy | 2 +- spec/fixtures/container_spring_boot_cli_valid_app/pogo_1.groovy | 2 +- spec/fixtures/container_spring_boot_cli_valid_app/pogo_2.groovy | 2 +- spec/fixtures/container_spring_boot_cli_valid_app/pogo_3.groovy | 2 +- .../.java-buildpack/tomcat/conf/context.xml | 2 +- .../.java-buildpack/tomcat/conf/server.xml | 2 +- spec/fixtures/container_tomcat_geode_store_context_after.xml | 2 +- spec/fixtures/container_tomcat_geode_store_server_after.xml | 2 +- .../.java-buildpack/tomcat/conf/context.xml | 2 +- spec/fixtures/container_tomcat_redis_store_context_after.xml | 2 +- spec/fixtures/container_tomcat_with_index/index.html | 2 +- spec/fixtures/framework_jrebel_app_simple/rebel-remote.xml | 2 +- .../framework_jrebel_app_war/WEB-INF/classes/rebel-remote.xml | 2 +- spec/fixtures/integration_long_detect_tag/config/components.yml | 2 +- .../lib/java_buildpack/container/long_detect_tags.rb | 2 +- spec/fixtures/integration_valid/system.properties | 2 +- spec/fixtures/test.properties | 2 +- spec/integration_helper.rb | 2 +- spec/internet_availability_helper.rb | 2 +- spec/java_buildpack/buildpack_spec.rb | 2 +- spec/java_buildpack/buildpack_version_spec.rb | 2 +- spec/java_buildpack/component/additional_libraries_spec.rb | 2 +- spec/java_buildpack/component/application_spec.rb | 2 +- spec/java_buildpack/component/base_component_spec.rb | 2 +- spec/java_buildpack/component/droplet_spec.rb | 2 +- spec/java_buildpack/component/environment_variables_spec.rb | 2 +- spec/java_buildpack/component/extension_directories_spec.rb | 2 +- spec/java_buildpack/component/immutable_java_home_spec.rb | 2 +- spec/java_buildpack/component/java_opts_spec.rb | 2 +- spec/java_buildpack/component/modular_component_spec.rb | 2 +- spec/java_buildpack/component/mutable_java_home_spec.rb | 2 +- spec/java_buildpack/component/security_providers_spec.rb | 2 +- spec/java_buildpack/component/services_spec.rb | 2 +- .../component/versioned_dependency_component_spec.rb | 2 +- spec/java_buildpack/container/dist_zip_like_spec.rb | 2 +- spec/java_buildpack/container/dist_zip_spec.rb | 2 +- spec/java_buildpack/container/groovy_spec.rb | 2 +- spec/java_buildpack/container/java_main_spec.rb | 2 +- spec/java_buildpack/container/play_framework_spec.rb | 2 +- spec/java_buildpack/container/ratpack_spec.rb | 2 +- spec/java_buildpack/container/spring_boot_cli_spec.rb | 2 +- spec/java_buildpack/container/spring_boot_spec.rb | 2 +- .../container/tomcat/tomcat_access_logging_support_spec.rb | 2 +- .../container/tomcat/tomcat_external_configuration_spec.rb | 2 +- spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb | 2 +- .../container/tomcat/tomcat_insight_support_spec.rb | 2 +- spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb | 2 +- .../container/tomcat/tomcat_lifecycle_support_spec.rb | 2 +- .../container/tomcat/tomcat_logging_support_spec.rb | 2 +- spec/java_buildpack/container/tomcat/tomcat_redis_store_spec.rb | 2 +- spec/java_buildpack/container/tomcat/tomcat_setenv_spec.rb | 2 +- spec/java_buildpack/container/tomcat_spec.rb | 2 +- spec/java_buildpack/framework/app_dynamics_agent_spec.rb | 2 +- spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb | 2 +- .../framework/azure_application_insights_agent_spec.rb | 2 +- spec/java_buildpack/framework/client_certificate_mapper_spec.rb | 2 +- spec/java_buildpack/framework/container_customizer_spec.rb | 2 +- .../framework/container_security_provider_spec.rb | 2 +- spec/java_buildpack/framework/debug_spec.rb | 2 +- .../framework/dyadic_ekm_security_provider_spec.rb | 2 +- spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb | 2 +- spec/java_buildpack/framework/dynatrace_one_agent_spec.rb | 2 +- .../framework/google_stackdriver_debugger_spec.rb | 2 +- .../framework/google_stackdriver_profiler_spec.rb | 2 +- spec/java_buildpack/framework/introscope_agent_spec.rb | 2 +- .../framework/java_memory_assistant/agent_spec.rb | 2 +- .../framework/java_memory_assistant/clean_up_spec.rb | 2 +- .../framework/java_memory_assistant/heap_dump_folder_spec.rb | 2 +- spec/java_buildpack/framework/java_memory_assistant_spec.rb | 2 +- spec/java_buildpack/framework/java_opts_spec.rb | 2 +- spec/java_buildpack/framework/java_security_spec.rb | 2 +- spec/java_buildpack/framework/jmx_spec.rb | 2 +- spec/java_buildpack/framework/jprofiler_profiler_spec.rb | 2 +- spec/java_buildpack/framework/jrebel_agent_spec.rb | 2 +- spec/java_buildpack/framework/luna_security_provider_spec.rb | 2 +- spec/java_buildpack/framework/maria_db_jdbc_spec.rb | 2 +- spec/java_buildpack/framework/metric_writer_spec.rb | 2 +- spec/java_buildpack/framework/multi_buildpack_spec.rb | 2 +- spec/java_buildpack/framework/new_relic_agent_spec.rb | 2 +- spec/java_buildpack/framework/postgresql_jdbc_spec.rb | 2 +- .../framework/riverbed_appinternals_agent_spec.rb | 2 +- spec/java_buildpack/framework/sky_walking_agent_spec.rb | 2 +- .../framework/spring_auto_reconfiguration_spec.rb | 2 +- spec/java_buildpack/framework/spring_insight_spec.rb | 2 +- spec/java_buildpack/framework/takipi_agent_spec.rb | 2 +- spec/java_buildpack/framework/your_kit_profiler_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_jre_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb | 2 +- .../java_buildpack/jre/open_jdk_like_security_providers_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_spec.rb | 2 +- spec/java_buildpack/logging/delegating_logger_spec.rb | 2 +- spec/java_buildpack/logging/logger_factory_spec.rb | 2 +- spec/java_buildpack/repository/configured_item_spec.rb | 2 +- spec/java_buildpack/repository/repository_index_spec.rb | 2 +- spec/java_buildpack/repository/version_resolver_spec.rb | 2 +- spec/java_buildpack/util/cache/application_cache_spec.rb | 2 +- spec/java_buildpack/util/cache/cache_factory_spec.rb | 2 +- spec/java_buildpack/util/cache/cached_file_spec.rb | 2 +- spec/java_buildpack/util/cache/download_cache_spec.rb | 2 +- spec/java_buildpack/util/cache/internet_availability_spec.rb | 2 +- spec/java_buildpack/util/cache/yield_file_with_content.rb | 2 +- spec/java_buildpack/util/configuration_utils_spec.rb | 2 +- spec/java_buildpack/util/constantize_spec.rb | 2 +- spec/java_buildpack/util/filtering_pathname_spec.rb | 2 +- spec/java_buildpack/util/format_duration_spec.rb | 2 +- spec/java_buildpack/util/java_main_utils_spec.rb | 2 +- spec/java_buildpack/util/play/base_spec.rb | 2 +- spec/java_buildpack/util/play/factory_spec.rb | 2 +- spec/java_buildpack/util/play/post22_dist_spec.rb | 2 +- spec/java_buildpack/util/play/post22_spec.rb | 2 +- spec/java_buildpack/util/play/post22_staged_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_dist_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_staged_spec.rb | 2 +- spec/java_buildpack/util/properties_spec.rb | 2 +- spec/java_buildpack/util/ratpack_utils_spec.rb | 2 +- spec/java_buildpack/util/sanitize_spec.rb | 2 +- spec/java_buildpack/util/shell_spec.rb | 2 +- spec/java_buildpack/util/spring_boot_utils_spec.rb | 2 +- spec/java_buildpack/util/tokenized_version_spec.rb | 2 +- spec/logging_helper.rb | 2 +- spec/memory_limit_helper.rb | 2 +- spec/spec_helper.rb | 2 +- 348 files changed, 348 insertions(+), 348 deletions(-) diff --git a/Rakefile b/Rakefile index 71476ba513..715d723e40 100644 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/compile b/bin/compile index 5f3df15a1d..be7589efc4 100755 --- a/bin/compile +++ b/bin/compile @@ -2,7 +2,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/detect b/bin/detect index 593b22e650..44d43d71af 100755 --- a/bin/detect +++ b/bin/detect @@ -2,7 +2,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/finalize b/bin/finalize index 3ccb3408b6..2a0330f27e 100755 --- a/bin/finalize +++ b/bin/finalize @@ -2,7 +2,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/release b/bin/release index ad188a3415..d301964313 100755 --- a/bin/release +++ b/bin/release @@ -2,7 +2,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/auto-merge.sh b/ci/auto-merge.sh index a14905142d..1bba3cb58d 100755 --- a/ci/auto-merge.sh +++ b/ci/auto-merge.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/auto-merge.yml b/ci/auto-merge.yml index 23e715bb29..79540a9322 100644 --- a/ci/auto-merge.yml +++ b/ci/auto-merge.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/package-test.sh b/ci/package-test.sh index 87a8bb7171..14e3e11198 100755 --- a/ci/package-test.sh +++ b/ci/package-test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/package-test.yml b/ci/package-test.yml index 5c3f77fbc6..dc8b91e273 100644 --- a/ci/package-test.yml +++ b/ci/package-test.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/unit-test.sh b/ci/unit-test.sh index 9aa63b52dd..29e76d676b 100755 --- a/ci/unit-test.sh +++ b/ci/unit-test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/unit-test.yml b/ci/unit-test.yml index aa48a695ad..cbd505426c 100644 --- a/ci/unit-test.yml +++ b/ci/unit-test.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-json.sh b/ci/versions-json.sh index 09ae0faa08..c03eb37b58 100755 --- a/ci/versions-json.sh +++ b/ci/versions-json.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-json.yml b/ci/versions-json.yml index a5e548ff18..1a26902879 100644 --- a/ci/versions-json.yml +++ b/ci/versions-json.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-markdown.sh b/ci/versions-markdown.sh index 9637e98154..4fb3958e9b 100755 --- a/ci/versions-markdown.sh +++ b/ci/versions-markdown.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-markdown.yml b/ci/versions-markdown.yml index 9d1dba92ce..1807c333d0 100644 --- a/ci/versions-markdown.yml +++ b/ci/versions-markdown.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-yaml.sh b/ci/versions-yaml.sh index 2ab1330488..2da7d35e3e 100755 --- a/ci/versions-yaml.sh +++ b/ci/versions-yaml.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-yaml.yml b/ci/versions-yaml.yml index 30c90dbeaf..46bdf6f766 100644 --- a/ci/versions-yaml.yml +++ b/ci/versions-yaml.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions.sh b/ci/versions.sh index 9e01141390..d7548a555c 100755 --- a/ci/versions.sh +++ b/ci/versions.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions.yml b/ci/versions.yml index 0d4f17d844..eb9e9ee824 100644 --- a/ci/versions.yml +++ b/ci/versions.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 79836f988f..258cc3c217 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/aspectj_weaver_agent.yml b/config/aspectj_weaver_agent.yml index 70f33fb3d4..891c9ff1d7 100644 --- a/config/aspectj_weaver_agent.yml +++ b/config/aspectj_weaver_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/azure_application_insights_agent.yml b/config/azure_application_insights_agent.yml index 71478411dd..c1e51023ca 100644 --- a/config/azure_application_insights_agent.yml +++ b/config/azure_application_insights_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/cache.yml b/config/cache.yml index 6528449872..e2b48f092b 100644 --- a/config/cache.yml +++ b/config/cache.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/client_certificate_mapper.yml b/config/client_certificate_mapper.yml index f13672e4a0..ea60acd0b3 100644 --- a/config/client_certificate_mapper.yml +++ b/config/client_certificate_mapper.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/components.yml b/config/components.yml index 1863871b04..33fea9d51b 100644 --- a/config/components.yml +++ b/config/components.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/container_customizer.yml b/config/container_customizer.yml index e6f6dd9761..4a62ca1bec 100644 --- a/config/container_customizer.yml +++ b/config/container_customizer.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/container_security_provider.yml b/config/container_security_provider.yml index 1eda4dfed0..912a43a109 100644 --- a/config/container_security_provider.yml +++ b/config/container_security_provider.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index 2c61ff2584..e3fd6bf7db 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/debug.yml b/config/debug.yml index 4263af9faf..8883a8d3c0 100644 --- a/config/debug.yml +++ b/config/debug.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/dyadic_ekm_security_provider.yml b/config/dyadic_ekm_security_provider.yml index 0c42d3ed6a..555817606c 100644 --- a/config/dyadic_ekm_security_provider.yml +++ b/config/dyadic_ekm_security_provider.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/dynatrace_appmon_agent.yml b/config/dynatrace_appmon_agent.yml index 7e9d57aa13..7849ebd7ed 100644 --- a/config/dynatrace_appmon_agent.yml +++ b/config/dynatrace_appmon_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/dynatrace_one_agent.yml b/config/dynatrace_one_agent.yml index 1e6216625d..e10e2c6535 100644 --- a/config/dynatrace_one_agent.yml +++ b/config/dynatrace_one_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/google_stackdriver_debugger.yml b/config/google_stackdriver_debugger.yml index e751b79fdd..99814bb547 100644 --- a/config/google_stackdriver_debugger.yml +++ b/config/google_stackdriver_debugger.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/google_stackdriver_profiler.yml b/config/google_stackdriver_profiler.yml index 6a65f9dfb4..5ec94f84a7 100644 --- a/config/google_stackdriver_profiler.yml +++ b/config/google_stackdriver_profiler.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/groovy.yml b/config/groovy.yml index 87f31276c6..d90959104d 100644 --- a/config/groovy.yml +++ b/config/groovy.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index 1ec08affe3..30380c586e 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/java_main.yml b/config/java_main.yml index 068ce1b6e5..481d771fc4 100644 --- a/config/java_main.yml +++ b/config/java_main.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/java_memory_assistant.yml b/config/java_memory_assistant.yml index 93aea0bcde..c4604fd873 100644 --- a/config/java_memory_assistant.yml +++ b/config/java_memory_assistant.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/java_opts.yml b/config/java_opts.yml index 9a1e648fa4..1fd2f7e1ca 100644 --- a/config/java_opts.yml +++ b/config/java_opts.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/jmx.yml b/config/jmx.yml index 0197a191a4..68b365c2d5 100644 --- a/config/jmx.yml +++ b/config/jmx.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/jprofiler_profiler.yml b/config/jprofiler_profiler.yml index b851f5e804..7de594ddb7 100644 --- a/config/jprofiler_profiler.yml +++ b/config/jprofiler_profiler.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml index 25db540f5c..78c1c69703 100644 --- a/config/jrebel_agent.yml +++ b/config/jrebel_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/logging.yml b/config/logging.yml index 9424053c0b..19dd8c9c86 100644 --- a/config/logging.yml +++ b/config/logging.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index 22702c2eee..ec8235c18c 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/maria_db_jdbc.yml b/config/maria_db_jdbc.yml index cdd39efd18..8d47924223 100644 --- a/config/maria_db_jdbc.yml +++ b/config/maria_db_jdbc.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/metric_writer.yml b/config/metric_writer.yml index ff5e024de0..22de9231aa 100644 --- a/config/metric_writer.yml +++ b/config/metric_writer.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/new_relic_agent.yml b/config/new_relic_agent.yml index f4c328a4cd..84e04f07f9 100644 --- a/config/new_relic_agent.yml +++ b/config/new_relic_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index dd37c71575..d6d2611a7a 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index e8250bb728..2ec915286e 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/postgresql_jdbc.yml b/config/postgresql_jdbc.yml index 99a7d286e9..bf153e71dd 100644 --- a/config/postgresql_jdbc.yml +++ b/config/postgresql_jdbc.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/repository.yml b/config/repository.yml index 733fcad92c..4951f18507 100644 --- a/config/repository.yml +++ b/config/repository.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/riverbed_appinternals_agent.yml b/config/riverbed_appinternals_agent.yml index 135ed49683..27b5ff97b9 100644 --- a/config/riverbed_appinternals_agent.yml +++ b/config/riverbed_appinternals_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/sky_walking_agent.yml b/config/sky_walking_agent.yml index af501435da..ce6cb013f9 100644 --- a/config/sky_walking_agent.yml +++ b/config/sky_walking_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/spring_auto_reconfiguration.yml b/config/spring_auto_reconfiguration.yml index 07695dd8c3..9825c39179 100644 --- a/config/spring_auto_reconfiguration.yml +++ b/config/spring_auto_reconfiguration.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/spring_boot_cli.yml b/config/spring_boot_cli.yml index bb833d222e..4144c5eddc 100644 --- a/config/spring_boot_cli.yml +++ b/config/spring_boot_cli.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/takipi_agent.yml b/config/takipi_agent.yml index e37316e51a..eb7adfb3dd 100644 --- a/config/takipi_agent.yml +++ b/config/takipi_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/tomcat.yml b/config/tomcat.yml index 8d386cee7b..8ab937b924 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml index eb8ecb65a8..287d4f01f4 100644 --- a/config/your_kit_profiler.yml +++ b/config/your_kit_profiler.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index abd9e8f78a..9e3d9d7c9a 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack.rb b/lib/java_buildpack.rb index ed8f33c039..ed3243e83f 100644 --- a/lib/java_buildpack.rb +++ b/lib/java_buildpack.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 36841333a8..03aea901f9 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index 8e85ff2d7e..b9a2e87c9c 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component.rb b/lib/java_buildpack/component.rb index 2d804925e5..512d16ff55 100644 --- a/lib/java_buildpack/component.rb +++ b/lib/java_buildpack/component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/additional_libraries.rb b/lib/java_buildpack/component/additional_libraries.rb index a05e3a7afe..e466be8edc 100644 --- a/lib/java_buildpack/component/additional_libraries.rb +++ b/lib/java_buildpack/component/additional_libraries.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index 50f66101c8..20c5da5416 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index a7e2d2396f..6af4d74517 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index 1f3244ce80..181c01507d 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/environment_variables.rb b/lib/java_buildpack/component/environment_variables.rb index 787076f08b..1789bc51fc 100644 --- a/lib/java_buildpack/component/environment_variables.rb +++ b/lib/java_buildpack/component/environment_variables.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/extension_directories.rb b/lib/java_buildpack/component/extension_directories.rb index 7938621663..5d419dfef1 100644 --- a/lib/java_buildpack/component/extension_directories.rb +++ b/lib/java_buildpack/component/extension_directories.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index fb501b99de..fc7aac42c5 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index 40ad1ee222..15fdabdf7b 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/modular_component.rb b/lib/java_buildpack/component/modular_component.rb index ce999a4a00..afe5b2dfce 100644 --- a/lib/java_buildpack/component/modular_component.rb +++ b/lib/java_buildpack/component/modular_component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index 286f2daa1e..6152a19c12 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/networking.rb b/lib/java_buildpack/component/networking.rb index d938b4705a..abbe922fd3 100644 --- a/lib/java_buildpack/component/networking.rb +++ b/lib/java_buildpack/component/networking.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/root_libraries.rb b/lib/java_buildpack/component/root_libraries.rb index 8cef844931..bc378ca6ad 100644 --- a/lib/java_buildpack/component/root_libraries.rb +++ b/lib/java_buildpack/component/root_libraries.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/security_providers.rb b/lib/java_buildpack/component/security_providers.rb index 649c69d270..c9388ee9a3 100644 --- a/lib/java_buildpack/component/security_providers.rb +++ b/lib/java_buildpack/component/security_providers.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/services.rb b/lib/java_buildpack/component/services.rb index e04e7d668c..7c8a55a386 100644 --- a/lib/java_buildpack/component/services.rb +++ b/lib/java_buildpack/component/services.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/versioned_dependency_component.rb b/lib/java_buildpack/component/versioned_dependency_component.rb index 2de5cac091..0ca0faea51 100644 --- a/lib/java_buildpack/component/versioned_dependency_component.rb +++ b/lib/java_buildpack/component/versioned_dependency_component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container.rb b/lib/java_buildpack/container.rb index f2b5278fa5..73287ff7ba 100644 --- a/lib/java_buildpack/container.rb +++ b/lib/java_buildpack/container.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/dist_zip.rb b/lib/java_buildpack/container/dist_zip.rb index c0170f11d2..88439d49dc 100644 --- a/lib/java_buildpack/container/dist_zip.rb +++ b/lib/java_buildpack/container/dist_zip.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 60f9a0aae6..60ae1997c5 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index 417f0643ac..54fdd84a81 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index 6170bcfa1b..d312f61815 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/play_framework.rb b/lib/java_buildpack/container/play_framework.rb index 8415f07049..fe56c78757 100644 --- a/lib/java_buildpack/container/play_framework.rb +++ b/lib/java_buildpack/container/play_framework.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/ratpack.rb b/lib/java_buildpack/container/ratpack.rb index 61e25e8d67..2ee28e719d 100644 --- a/lib/java_buildpack/container/ratpack.rb +++ b/lib/java_buildpack/container/ratpack.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/spring_boot.rb b/lib/java_buildpack/container/spring_boot.rb index 58fd692932..0bc7ad293d 100644 --- a/lib/java_buildpack/container/spring_boot.rb +++ b/lib/java_buildpack/container/spring_boot.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index 7f9132d6b9..838eb30b47 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 9557a5ef5a..12dd509b14 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb index 8eda928cda..113ce6e3e8 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb index a4a6576659..8a76c472a1 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 8b4599e5ed..f7166a020b 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb index 5f88d17920..4ae3e37fe1 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index 9587c0a369..58554062af 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb index 3ff7c676ab..74b0a8709d 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb index 390fddb518..10deced444 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb index 4164cc5c3c..99decee039 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_setenv.rb b/lib/java_buildpack/container/tomcat/tomcat_setenv.rb index d2bd721398..915af92806 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_setenv.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_setenv.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_utils.rb b/lib/java_buildpack/container/tomcat/tomcat_utils.rb index 97c26c3068..d46e8fa47b 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_utils.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework.rb b/lib/java_buildpack/framework.rb index d613e5371c..01345bb049 100644 --- a/lib/java_buildpack/framework.rb +++ b/lib/java_buildpack/framework.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 560aaa55da..5cca4d477c 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/aspectj_weaver_agent.rb b/lib/java_buildpack/framework/aspectj_weaver_agent.rb index fa65eb737f..d0b0e16866 100644 --- a/lib/java_buildpack/framework/aspectj_weaver_agent.rb +++ b/lib/java_buildpack/framework/aspectj_weaver_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/azure_application_insights_agent.rb b/lib/java_buildpack/framework/azure_application_insights_agent.rb index d2179debf6..ac14170029 100644 --- a/lib/java_buildpack/framework/azure_application_insights_agent.rb +++ b/lib/java_buildpack/framework/azure_application_insights_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/client_certificate_mapper.rb b/lib/java_buildpack/framework/client_certificate_mapper.rb index 25d24fc30a..0b0b0ba8ea 100644 --- a/lib/java_buildpack/framework/client_certificate_mapper.rb +++ b/lib/java_buildpack/framework/client_certificate_mapper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/container_customizer.rb b/lib/java_buildpack/framework/container_customizer.rb index c7954c11b7..a1c6fc731b 100644 --- a/lib/java_buildpack/framework/container_customizer.rb +++ b/lib/java_buildpack/framework/container_customizer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/container_security_provider.rb b/lib/java_buildpack/framework/container_security_provider.rb index 175e0fc512..7df14d6c37 100644 --- a/lib/java_buildpack/framework/container_security_provider.rb +++ b/lib/java_buildpack/framework/container_security_provider.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index 3aaa49235c..f2fc4ab379 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index 9b88d68ae4..ba497e03ec 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb index 7f845b20a3..53f30b74a2 100644 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb index 5dbbdf91f0..5f0c657d8c 100644 --- a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index d2b5a7aaf5..4ef267a15e 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/google_stackdriver_debugger.rb b/lib/java_buildpack/framework/google_stackdriver_debugger.rb index e26f20a718..cedbd80f91 100644 --- a/lib/java_buildpack/framework/google_stackdriver_debugger.rb +++ b/lib/java_buildpack/framework/google_stackdriver_debugger.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/google_stackdriver_profiler.rb b/lib/java_buildpack/framework/google_stackdriver_profiler.rb index ae5b041e6c..be7239b919 100644 --- a/lib/java_buildpack/framework/google_stackdriver_profiler.rb +++ b/lib/java_buildpack/framework/google_stackdriver_profiler.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index a6e9d716c5..0d22b87cfb 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_memory_assistant.rb b/lib/java_buildpack/framework/java_memory_assistant.rb index 74683d127c..d5e9000bb5 100644 --- a/lib/java_buildpack/framework/java_memory_assistant.rb +++ b/lib/java_buildpack/framework/java_memory_assistant.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_memory_assistant/agent.rb b/lib/java_buildpack/framework/java_memory_assistant/agent.rb index 57cc487208..7e5b4bab70 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/agent.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb b/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb index 57fa6ff955..02864a8965 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb index 75eb5eefff..1dc93c9713 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index 44d23554a3..2c4d3b28eb 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_security.rb b/lib/java_buildpack/framework/java_security.rb index 2b5c21d6b7..40aeac999b 100644 --- a/lib/java_buildpack/framework/java_security.rb +++ b/lib/java_buildpack/framework/java_security.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 274f1280ef..65da1f0f11 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/jprofiler_profiler.rb b/lib/java_buildpack/framework/jprofiler_profiler.rb index 7a2ef50f1b..561d382658 100644 --- a/lib/java_buildpack/framework/jprofiler_profiler.rb +++ b/lib/java_buildpack/framework/jprofiler_profiler.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index 62832c1ebb..d1e510da37 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index ece9633cf6..cdfac61140 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/maria_db_jdbc.rb b/lib/java_buildpack/framework/maria_db_jdbc.rb index bd472822ab..db8806abe8 100644 --- a/lib/java_buildpack/framework/maria_db_jdbc.rb +++ b/lib/java_buildpack/framework/maria_db_jdbc.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/metric_writer.rb b/lib/java_buildpack/framework/metric_writer.rb index 41fbf1ea86..08cfc68c42 100644 --- a/lib/java_buildpack/framework/metric_writer.rb +++ b/lib/java_buildpack/framework/metric_writer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/multi_buildpack.rb b/lib/java_buildpack/framework/multi_buildpack.rb index 384336bded..9d78f1318b 100644 --- a/lib/java_buildpack/framework/multi_buildpack.rb +++ b/lib/java_buildpack/framework/multi_buildpack.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 89a9cc69e9..2ac29cb30d 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/postgresql_jdbc.rb b/lib/java_buildpack/framework/postgresql_jdbc.rb index 1c4a347a24..576edf45eb 100644 --- a/lib/java_buildpack/framework/postgresql_jdbc.rb +++ b/lib/java_buildpack/framework/postgresql_jdbc.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb index 984ff70fe8..f856cdd759 100644 --- a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb +++ b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/sky_walking_agent.rb b/lib/java_buildpack/framework/sky_walking_agent.rb index abf779d13b..8daa5de585 100644 --- a/lib/java_buildpack/framework/sky_walking_agent.rb +++ b/lib/java_buildpack/framework/sky_walking_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 4837f1df10..5e5db78ecf 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/spring_insight.rb b/lib/java_buildpack/framework/spring_insight.rb index e75bc23c71..5f3deae416 100644 --- a/lib/java_buildpack/framework/spring_insight.rb +++ b/lib/java_buildpack/framework/spring_insight.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index 44ccf6a9b9..d5abfd900f 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/your_kit_profiler.rb b/lib/java_buildpack/framework/your_kit_profiler.rb index 5d38d7df4e..db7f6dfd9d 100644 --- a/lib/java_buildpack/framework/your_kit_profiler.rb +++ b/lib/java_buildpack/framework/your_kit_profiler.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre.rb b/lib/java_buildpack/jre.rb index 9f2e58791e..4f69bd76ff 100644 --- a/lib/java_buildpack/jre.rb +++ b/lib/java_buildpack/jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_jre.rb b/lib/java_buildpack/jre/open_jdk_jre.rb index b03e292c7f..9ff5ce4d27 100644 --- a/lib/java_buildpack/jre/open_jdk_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like.rb b/lib/java_buildpack/jre/open_jdk_like.rb index c9e7308a5e..5b4fa3e1ef 100644 --- a/lib/java_buildpack/jre/open_jdk_like.rb +++ b/lib/java_buildpack/jre/open_jdk_like.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index e42e8cc613..243bdbf012 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 9d7618e556..70c08f0b17 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb index 0804a5d442..31872049c3 100644 --- a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb +++ b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/oracle_jre.rb b/lib/java_buildpack/jre/oracle_jre.rb index f65350d0f8..a1312219c4 100644 --- a/lib/java_buildpack/jre/oracle_jre.rb +++ b/lib/java_buildpack/jre/oracle_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/logging.rb b/lib/java_buildpack/logging.rb index ae32467fec..58958e0c09 100644 --- a/lib/java_buildpack/logging.rb +++ b/lib/java_buildpack/logging.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/logging/delegating_logger.rb b/lib/java_buildpack/logging/delegating_logger.rb index 8bb296ef2f..b2ce8dff31 100644 --- a/lib/java_buildpack/logging/delegating_logger.rb +++ b/lib/java_buildpack/logging/delegating_logger.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/logging/logger_factory.rb b/lib/java_buildpack/logging/logger_factory.rb index 15668e9c7b..503308d857 100644 --- a/lib/java_buildpack/logging/logger_factory.rb +++ b/lib/java_buildpack/logging/logger_factory.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository.rb b/lib/java_buildpack/repository.rb index 28d3d7d816..4acde691fa 100644 --- a/lib/java_buildpack/repository.rb +++ b/lib/java_buildpack/repository.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/configured_item.rb b/lib/java_buildpack/repository/configured_item.rb index 7c0ebc51cd..02f19d9ced 100644 --- a/lib/java_buildpack/repository/configured_item.rb +++ b/lib/java_buildpack/repository/configured_item.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 84298e7587..e80ba63c3f 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/version_resolver.rb b/lib/java_buildpack/repository/version_resolver.rb index df779fb28a..6e2a6be7ec 100644 --- a/lib/java_buildpack/repository/version_resolver.rb +++ b/lib/java_buildpack/repository/version_resolver.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util.rb b/lib/java_buildpack/util.rb index 0172bbb261..49b1c2cab1 100644 --- a/lib/java_buildpack/util.rb +++ b/lib/java_buildpack/util.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache.rb b/lib/java_buildpack/util/cache.rb index f4e94f6709..b5a9abcc9f 100644 --- a/lib/java_buildpack/util/cache.rb +++ b/lib/java_buildpack/util/cache.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/application_cache.rb b/lib/java_buildpack/util/cache/application_cache.rb index 90264ec521..cfc31f6ec2 100644 --- a/lib/java_buildpack/util/cache/application_cache.rb +++ b/lib/java_buildpack/util/cache/application_cache.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/cache_factory.rb b/lib/java_buildpack/util/cache/cache_factory.rb index 9856511ed0..6fe9a97503 100644 --- a/lib/java_buildpack/util/cache/cache_factory.rb +++ b/lib/java_buildpack/util/cache/cache_factory.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/cached_file.rb b/lib/java_buildpack/util/cache/cached_file.rb index 17f3452e9a..7e77dd5197 100644 --- a/lib/java_buildpack/util/cache/cached_file.rb +++ b/lib/java_buildpack/util/cache/cached_file.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 32edb06765..9b513242db 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/inferred_network_failure.rb b/lib/java_buildpack/util/cache/inferred_network_failure.rb index b1eef9c5fc..4b94ba7c01 100644 --- a/lib/java_buildpack/util/cache/inferred_network_failure.rb +++ b/lib/java_buildpack/util/cache/inferred_network_failure.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/internet_availability.rb b/lib/java_buildpack/util/cache/internet_availability.rb index 9b174062ae..b66c397a0b 100644 --- a/lib/java_buildpack/util/cache/internet_availability.rb +++ b/lib/java_buildpack/util/cache/internet_availability.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/class_file_utils.rb b/lib/java_buildpack/util/class_file_utils.rb index d61f46d0d3..a8750164c9 100644 --- a/lib/java_buildpack/util/class_file_utils.rb +++ b/lib/java_buildpack/util/class_file_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/colorize.rb b/lib/java_buildpack/util/colorize.rb index 887ce18103..0db820ede4 100644 --- a/lib/java_buildpack/util/colorize.rb +++ b/lib/java_buildpack/util/colorize.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 46fee0fbee..33c13f5ca5 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/constantize.rb b/lib/java_buildpack/util/constantize.rb index 1c5cbf4480..74ac83fa20 100644 --- a/lib/java_buildpack/util/constantize.rb +++ b/lib/java_buildpack/util/constantize.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/dash_case.rb b/lib/java_buildpack/util/dash_case.rb index b1fdc77025..539a9f030e 100644 --- a/lib/java_buildpack/util/dash_case.rb +++ b/lib/java_buildpack/util/dash_case.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/file_enumerable.rb b/lib/java_buildpack/util/file_enumerable.rb index 0c93088870..74b1ca1642 100644 --- a/lib/java_buildpack/util/file_enumerable.rb +++ b/lib/java_buildpack/util/file_enumerable.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/filtering_pathname.rb b/lib/java_buildpack/util/filtering_pathname.rb index 4abc96479a..b2fbf9ad98 100644 --- a/lib/java_buildpack/util/filtering_pathname.rb +++ b/lib/java_buildpack/util/filtering_pathname.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/find_single_directory.rb b/lib/java_buildpack/util/find_single_directory.rb index edae7d0b63..01c0e41841 100644 --- a/lib/java_buildpack/util/find_single_directory.rb +++ b/lib/java_buildpack/util/find_single_directory.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/format_duration.rb b/lib/java_buildpack/util/format_duration.rb index 9a8322305a..a3d90a8d4d 100644 --- a/lib/java_buildpack/util/format_duration.rb +++ b/lib/java_buildpack/util/format_duration.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/groovy_utils.rb b/lib/java_buildpack/util/groovy_utils.rb index df009154e2..f539005ca9 100644 --- a/lib/java_buildpack/util/groovy_utils.rb +++ b/lib/java_buildpack/util/groovy_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/jar_finder.rb b/lib/java_buildpack/util/jar_finder.rb index e5e1eb5efc..9929755307 100644 --- a/lib/java_buildpack/util/jar_finder.rb +++ b/lib/java_buildpack/util/jar_finder.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/java_main_utils.rb b/lib/java_buildpack/util/java_main_utils.rb index b87dbf0d4d..d77197d720 100644 --- a/lib/java_buildpack/util/java_main_utils.rb +++ b/lib/java_buildpack/util/java_main_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play.rb b/lib/java_buildpack/util/play.rb index 1767055d35..185fdde87a 100644 --- a/lib/java_buildpack/util/play.rb +++ b/lib/java_buildpack/util/play.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/base.rb b/lib/java_buildpack/util/play/base.rb index fa225f8750..7dcc59454f 100644 --- a/lib/java_buildpack/util/play/base.rb +++ b/lib/java_buildpack/util/play/base.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/factory.rb b/lib/java_buildpack/util/play/factory.rb index a772eb5200..de52ca31e8 100644 --- a/lib/java_buildpack/util/play/factory.rb +++ b/lib/java_buildpack/util/play/factory.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/post22.rb b/lib/java_buildpack/util/play/post22.rb index fcc0117851..9eb042b3d9 100644 --- a/lib/java_buildpack/util/play/post22.rb +++ b/lib/java_buildpack/util/play/post22.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/post22_dist.rb b/lib/java_buildpack/util/play/post22_dist.rb index 3571c7ef51..04cf3c40ec 100644 --- a/lib/java_buildpack/util/play/post22_dist.rb +++ b/lib/java_buildpack/util/play/post22_dist.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/post22_staged.rb b/lib/java_buildpack/util/play/post22_staged.rb index ed68b7ece8..2875f75eb3 100644 --- a/lib/java_buildpack/util/play/post22_staged.rb +++ b/lib/java_buildpack/util/play/post22_staged.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/pre22.rb b/lib/java_buildpack/util/play/pre22.rb index 138ece7912..d2f1197f64 100644 --- a/lib/java_buildpack/util/play/pre22.rb +++ b/lib/java_buildpack/util/play/pre22.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/pre22_dist.rb b/lib/java_buildpack/util/play/pre22_dist.rb index a3b2d6a919..2614a40caa 100644 --- a/lib/java_buildpack/util/play/pre22_dist.rb +++ b/lib/java_buildpack/util/play/pre22_dist.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/pre22_staged.rb b/lib/java_buildpack/util/play/pre22_staged.rb index 52dd1a7a7e..a4de33e84a 100644 --- a/lib/java_buildpack/util/play/pre22_staged.rb +++ b/lib/java_buildpack/util/play/pre22_staged.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/properties.rb b/lib/java_buildpack/util/properties.rb index 82ee6626dc..5e35e7551d 100644 --- a/lib/java_buildpack/util/properties.rb +++ b/lib/java_buildpack/util/properties.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/qualify_path.rb b/lib/java_buildpack/util/qualify_path.rb index 53ac6f4dd5..52a360a2f9 100644 --- a/lib/java_buildpack/util/qualify_path.rb +++ b/lib/java_buildpack/util/qualify_path.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/ratpack_utils.rb b/lib/java_buildpack/util/ratpack_utils.rb index 304d89c90c..571d445288 100644 --- a/lib/java_buildpack/util/ratpack_utils.rb +++ b/lib/java_buildpack/util/ratpack_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index aa7f4bd015..4673135783 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/shell.rb b/lib/java_buildpack/util/shell.rb index 980eae8ec1..f0a768f80e 100644 --- a/lib/java_buildpack/util/shell.rb +++ b/lib/java_buildpack/util/shell.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/snake_case.rb b/lib/java_buildpack/util/snake_case.rb index eb17496b26..3a0f28f94b 100644 --- a/lib/java_buildpack/util/snake_case.rb +++ b/lib/java_buildpack/util/snake_case.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/space_case.rb b/lib/java_buildpack/util/space_case.rb index b9d8480b75..12a02f226e 100644 --- a/lib/java_buildpack/util/space_case.rb +++ b/lib/java_buildpack/util/space_case.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/spring_boot_utils.rb b/lib/java_buildpack/util/spring_boot_utils.rb index 52bde420a9..eeef1d9d70 100644 --- a/lib/java_buildpack/util/spring_boot_utils.rb +++ b/lib/java_buildpack/util/spring_boot_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/start_script.rb b/lib/java_buildpack/util/start_script.rb index 3a4a08058e..c5867ccc01 100644 --- a/lib/java_buildpack/util/start_script.rb +++ b/lib/java_buildpack/util/start_script.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/to_b.rb b/lib/java_buildpack/util/to_b.rb index f25d6d2b16..c7349d4881 100644 --- a/lib/java_buildpack/util/to_b.rb +++ b/lib/java_buildpack/util/to_b.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index 8ce0c2839f..57bcdd55d8 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 2a577d4af3..e0c7ed4412 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/package.rb b/rakelib/package.rb index 6a80200cee..2f10ade1e1 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/package_task.rb b/rakelib/package_task.rb index 4abb15eebc..1d7b7ae43f 100644 --- a/rakelib/package_task.rb +++ b/rakelib/package_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/stage_buildpack_task.rb b/rakelib/stage_buildpack_task.rb index a52351f4b0..2a13f58ca9 100644 --- a/rakelib/stage_buildpack_task.rb +++ b/rakelib/stage_buildpack_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 20dfcfff55..4065a0e1df 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2019 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/resources/azure_application_insights_agent/AI-Agent.xml b/resources/azure_application_insights_agent/AI-Agent.xml index e508e3e087..53355d659c 100644 --- a/resources/azure_application_insights_agent/AI-Agent.xml +++ b/resources/azure_application_insights_agent/AI-Agent.xml @@ -1,6 +1,6 @@ +--> From af2e9b6f03aa634e9f430d265e95df3f195b9d9b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 9 Jan 2019 08:26:09 -0800 Subject: [PATCH 484/812] Errant Log Statement This change removes an errant log statement that was left in during build failure diagnosis. [resolges #673] Signed-off-by: Ben Hale --- lib/java_buildpack/component/extension_directories.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/java_buildpack/component/extension_directories.rb b/lib/java_buildpack/component/extension_directories.rb index 29d1c01922..5d419dfef1 100644 --- a/lib/java_buildpack/component/extension_directories.rb +++ b/lib/java_buildpack/component/extension_directories.rb @@ -38,8 +38,6 @@ def initialize(droplet_root) # # @return [String] the contents of the collection as a colon-delimited collection of paths def as_paths - each { |a| puts "#{a.class}: #{a}" } - qualified_paths = sort.map { |path| qualify_path path } qualified_paths.join ':' unless empty? end From 47e68dae5fcf21ec7b3cf126a7fc43c9e89c758c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 14 Jan 2019 11:16:23 -0800 Subject: [PATCH 485/812] Polishing Signed-off-by: Ben Hale --- config/new_relic_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/new_relic_agent.yml b/config/new_relic_agent.yml index 950c68ba16..2820bd00f3 100644 --- a/config/new_relic_agent.yml +++ b/config/new_relic_agent.yml @@ -19,4 +19,4 @@ version: 4.+ repository_root: https://download.run.pivotal.io/new-relic extensions: version: 1.+ - repository_root: \ No newline at end of file + repository_root: From 0dc25856cb5282481136fa66656856d45ce08aa3 Mon Sep 17 00:00:00 2001 From: Eric Stadtherr Date: Thu, 17 Jan 2019 15:20:15 -0700 Subject: [PATCH 486/812] Internet Availability During Initialization Previously, when the Tomcat External Configuration dependency was resolved Internet availability was only guaranteed during the dependency download, not during the index download. This change updates the code to resolve the index with the same guarantee. [#676] Signed-off-by: Ben Hale --- .../container/tomcat/tomcat_external_configuration.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb index 8a76c472a1..2fbc1fa874 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb @@ -25,6 +25,15 @@ module Container class TomcatExternalConfiguration < JavaBuildpack::Component::VersionedDependencyComponent include JavaBuildpack::Container + # (see JavaBuildpack::Component::VersionedDependencyComponent#initialize) + def initialize(context, &version_validator) + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, 'The Tomcat External Configuration download location is always accessible' + ) do + super(context) + end + end + # (see JavaBuildpack::Component::BaseComponent#compile) def compile JavaBuildpack::Util::Cache::InternetAvailability.instance.available( From 01e06164b0680da8126b7caa61d73cf10d58ced6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 18 Jan 2019 10:35:31 -0800 Subject: [PATCH 487/812] Extending Solution This change extends the same solution to New Relic Extension downloads. [resolves #676] Signed-off-by: Ben Hale --- .idea/.rakeTasks | 2 +- .../tomcat/tomcat_external_configuration.rb | 8 +++----- lib/java_buildpack/framework/new_relic_agent.rb | 12 +++++++++++- .../tomcat/tomcat_external_configuration_spec.rb | 1 + .../java_buildpack/framework/new_relic_agent_spec.rb | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks index c9f378181c..b706043389 100644 --- a/.idea/.rakeTasks +++ b/.idea/.rakeTasks @@ -4,4 +4,4 @@ You are allowed to: 1. Remove rake task 2. Add existing rake tasks To add existing rake tasks automatically delete this file and reload the project. ---> +--> diff --git a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb index 2fbc1fa874..65d3f43886 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb @@ -30,17 +30,15 @@ def initialize(context, &version_validator) JavaBuildpack::Util::Cache::InternetAvailability.instance.available( true, 'The Tomcat External Configuration download location is always accessible' ) do - super(context) + super(context, &version_validator) end end # (see JavaBuildpack::Component::BaseComponent#compile) def compile JavaBuildpack::Util::Cache::InternetAvailability.instance.available( - true, 'The Tomcat External Configuration download location is always accessible' - ) do - download_tar - end + true, 'The Tomcat External Configuration download location is always accessible', &method(:download_tar) + ) end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 80a3d36a60..34dc38e92c 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -93,10 +93,20 @@ def write_java_opts(java_opts, configuration) # Used by the main NewRelicAgent class to download the extensions tarball(if configured) class NewRelicAgentExtensions < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::VersionedDependencyComponent#initialize) + def initialize(context, &version_validator) + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, 'The New Relic Extensions download location is always accessible' + ) do + super(context, &version_validator) + end + end + # (see JavaBuildpack::Component::BaseComponent#compile) def compile JavaBuildpack::Util::Cache::InternetAvailability.instance.available( - true, "The #{@component_name} download location is always accessible" + true, 'The New Relic Extensions download location is always accessible' ) do download_tar(true, @droplet.sandbox + 'extensions') end diff --git a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb index 65c26ad797..72afda0d4f 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_external_configuration_spec.rb @@ -35,6 +35,7 @@ expect_any_instance_of(JavaBuildpack::Util::Cache::InternetAvailability) .to receive(:available).with(true, 'The Tomcat External Configuration download location is always accessible') + .twice component.compile end diff --git a/spec/java_buildpack/framework/new_relic_agent_spec.rb b/spec/java_buildpack/framework/new_relic_agent_spec.rb index fb56108d14..f274d7fdb0 100644 --- a/spec/java_buildpack/framework/new_relic_agent_spec.rb +++ b/spec/java_buildpack/framework/new_relic_agent_spec.rb @@ -126,7 +126,7 @@ cache_fixture: 'stub-new-relic-extensions.tar.gz' do expect_any_instance_of(JavaBuildpack::Util::Cache::InternetAvailability) - .to receive(:available).with(true, 'The New Relic Agent Extensions download location is always accessible') + .to receive(:available).with(true, 'The New Relic Extensions download location is always accessible').twice component.compile end From ef9098b7d58669867a167b7394dfce34e6aa972d Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 22 Jan 2019 09:38:04 -0800 Subject: [PATCH 488/812] Remove rake tasks metadata Signed-off-by: Ben Hale --- .gitignore | 1 + .idea/.rakeTasks | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 .idea/.rakeTasks diff --git a/.gitignore b/.gitignore index 2ac22b33dc..c3b086ec31 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea/.rakeTasks .idea/tasks.xml .idea/workspace.xml .yardoc diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks deleted file mode 100644 index b706043389..0000000000 --- a/.idea/.rakeTasks +++ /dev/null @@ -1,7 +0,0 @@ - - From eeef050a1573771c3847732c3dbd658201ad67ba Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 30 Jan 2019 09:59:57 -0800 Subject: [PATCH 489/812] Spring Boot CLI 2.x Signed-off-by: Ben Hale --- config/spring_boot_cli.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/spring_boot_cli.yml b/config/spring_boot_cli.yml index 4144c5eddc..c7d35462c8 100644 --- a/config/spring_boot_cli.yml +++ b/config/spring_boot_cli.yml @@ -17,5 +17,5 @@ # Note that the repository is shared with the Play Auto Reconfiguration framework and should be kept in step to # avoid conflicts. --- -version: 1.+ +version: 2.+ repository_root: "{default.repository.root}/spring-boot-cli" From 4fc69fa147a02c6ba77fe9852ef0899b2f179c29 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 30 Jan 2019 10:25:15 -0800 Subject: [PATCH 490/812] Groovy 2.6.+ Signed-off-by: Ben Hale --- config/groovy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/groovy.yml b/config/groovy.yml index d90959104d..739d2aac06 100644 --- a/config/groovy.yml +++ b/config/groovy.yml @@ -15,5 +15,5 @@ # Configuration for the Groovy container --- -version: 2.4.+ +version: 2.6.+ repository_root: "{default.repository.root}/groovy" From 401db407550a72e0d3eb0514619077f4413662e6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 30 Jan 2019 10:27:00 -0800 Subject: [PATCH 491/812] Revert "Groovy 2.6.+" This reverts commit 4fc69fa147a02c6ba77fe9852ef0899b2f179c29. --- config/groovy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/groovy.yml b/config/groovy.yml index 739d2aac06..d90959104d 100644 --- a/config/groovy.yml +++ b/config/groovy.yml @@ -15,5 +15,5 @@ # Configuration for the Groovy container --- -version: 2.6.+ +version: 2.4.+ repository_root: "{default.repository.root}/groovy" From b57492f145bdc0c35830388699402f1569e48bd3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 30 Jan 2019 10:50:21 -0800 Subject: [PATCH 492/812] NewRelic Extension Warnings Previously, New Relic Extensions would cause warnings even if no New Relic Extensions were provided. This change ensures that those warnings only show if extensions are available. Signed-off-by: Ben Hale --- lib/java_buildpack/framework/new_relic_agent.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index 34dc38e92c..f3d21d25c0 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -29,13 +29,16 @@ def initialize(context, &version_validator) extensions_context = context.clone extensions_context[:configuration] = context[:configuration]['extensions'] || {} + + return unless supports_extensions?(extensions_context[:configuration]) + @extensions = NewRelicAgentExtensions.new(extensions_context) end # (see JavaBuildpack::Component::BaseComponent#compile) def compile download_jar - @extensions.compile if @extensions.supports? + @extensions&.compile @droplet.copy_resources end @@ -83,6 +86,10 @@ def apply_user_configuration(credentials, configuration) end end + def supports_extensions?(configuration) + !(configuration['repository_root'] || '').empty? + end + def write_java_opts(java_opts, configuration) configuration.each do |key, value| java_opts.add_system_property("newrelic.config.#{key}", value) From da764e07baac594622a377e79a4e6872c454b85c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 14 Feb 2019 07:55:03 -0800 Subject: [PATCH 493/812] Tomcat 9.x Signed-off-by: Ben Hale --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index 8ab937b924..8a38110674 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -16,7 +16,7 @@ # Configuration for the Tomcat container --- tomcat: - version: 8.5.+ + version: 9.+ repository_root: "{default.repository.root}/tomcat" context_path: external_configuration_enabled: false From aeb07509187a3a06aeed85096b98745f814e1888 Mon Sep 17 00:00:00 2001 From: fwanggg Date: Thu, 13 Dec 2018 10:05:54 -0500 Subject: [PATCH 494/812] Download Agent from Broker This change enables the integration to download the agent from the broker if the broker advertises it. This will ensure that the buildpack contributed version of agent always matches the broker and therefore the server. [resolves #681] Signed-off-by: Ben Hale --- docs/framework-riverbed_appinternals_agent.md | 5 ++++ .../framework/riverbed_appinternals_agent.rb | 25 +++++++++++++++++-- .../riverbed_appinternals_agent_spec.rb | 7 ++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/docs/framework-riverbed_appinternals_agent.md b/docs/framework-riverbed_appinternals_agent.md index 606e1b37b3..2171d737ea 100644 --- a/docs/framework-riverbed_appinternals_agent.md +++ b/docs/framework-riverbed_appinternals_agent.md @@ -47,3 +47,8 @@ The framework can be configured by modifying the [`config/riverbed_appinternals_ [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering [`config/riverbed_appinternals_agent.yml`]: ../config/riverbed_appinternals_agent.yml + + +**NOTE** + +If the Riverbed Service Broker's version is greater than or equal to 10.20, the buildpack will instead download Riverbed AppInternals agent from Riverbed Service Broker and will fall back to using `repository_root` in [`config/riverbed_appinternals_agent.yml`][] only if Service Broker failed to serve the Agent artifact. diff --git a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb index f856cdd759..b56c4455fc 100644 --- a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb +++ b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb @@ -24,6 +24,14 @@ module Framework # Encapsulates the functionality for running the Riverbed Appinternals Agent support. class RiverbedAppinternalsAgent < JavaBuildpack::Component::VersionedDependencyComponent + # Creates an instance + # + # @param [Hash] context a collection of utilities used the component + def initialize(context) + super(context) + @uri = download_url(credentials, @uri) + end + # (see JavaBuildpack::Component::BaseComponent#compile) def compile download_zip(false, @droplet.sandbox, @component_name) @@ -32,8 +40,6 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER)['credentials'] - @droplet.environment_variables .add_environment_variable('AIX_INSTRUMENT_ALL', 1) .add_environment_variable('DSA_PORT', dsa_port(credentials)) @@ -57,6 +63,8 @@ def supports? private + PROFILERURL = 'profilerUrlLinux' + FILTER = /appinternals/.freeze private_constant :FILTER @@ -65,6 +73,14 @@ def agent_path @droplet.sandbox + 'agent/lib' + lib_name end + def credentials + service['credentials'] unless service.nil? + end + + def service + @application.services.find_service(FILTER) + end + def agent_port(credentials) credentials['rvbd_agent_port'] || 7073 end @@ -84,6 +100,11 @@ def lib_name def rvbd_moniker(credentials) credentials['rvbd_moniker'] || @configuration['rvbd_moniker'] end + + def download_url(credentials, default_url) + (credentials[PROFILERURL] unless credentials.nil?) || default_url + end + end end end diff --git a/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb b/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb index e8917a488e..e692bea804 100644 --- a/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb +++ b/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb @@ -30,6 +30,13 @@ before do allow(services).to receive(:one_service?).with(/appinternals/).and_return(true) + + allow(services).to receive(:find_service).and_return('credentials' => { 'profilerUrlLinux' => + 'http://testfoobar/profiler.zip' }) + + allow(application_cache).to receive(:get).with('http://testfoobar/profiler.zip') + .and_yield(Pathname.new('spec/fixtures/'\ + 'stub-riverbed-appinternals-agent.zip').open, false) end it 'detects with riverbed-appinternals-agent service' do From 3b8711447bbb5c884158d02b752ee9c4917a4a6a Mon Sep 17 00:00:00 2001 From: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com> Date: Mon, 4 Feb 2019 16:35:52 +0900 Subject: [PATCH 495/812] Fix typo in markdown In 817d004cd58505045e72f65ce81fdd429edc3077 this got messed up. Signed-off-by: Ben Hale [resolves #682] --- docs/jre-zulu_jre.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index 375a8501c9..7ff4c44fe7 100644 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -123,8 +123,7 @@ The amount of memory that should be allocated to stacks is given as an amount of stack_threads: 500 ``` -Note that the default value of 250 threads is optimized for a default Tomcat configuration. If you are using another container, especially something non-blocking like Netty, it's more appropriate to use a significantly smaller value. Typically 25 threads would cover the needs of both the server (Netty) and the threads started by the JVM itself.hreads: 500 -``` +Note that the default value of 250 threads is optimized for a default Tomcat configuration. If you are using another container, especially something non-blocking like Netty, it's more appropriate to use a significantly smaller value. Typically 25 threads would cover the needs of both the server (Netty) and the threads started by the JVM itself. #### Java Options From 35a60a919f559247410bb053faeba55bd172b7b8 Mon Sep 17 00:00:00 2001 From: Pavan Krishna Date: Wed, 6 Feb 2019 20:03:47 -0800 Subject: [PATCH 496/812] Cloud Foundry-specific Configuration This change adds default app-agent-config.xml file that excludes VCAP_* environment variables by default. This protects users in Cloud Foundry environments from exposing credentials from places like VCAP_SERVICES. [#684] Signed-off-by: Ben Hale --- .../framework/app_dynamics_agent.rb | 19 + .../defaults/conf/app-agent-config.xml | 702 ++++++++++++++++++ 2 files changed, 721 insertions(+) create mode 100644 resources/app_dynamics_agent/defaults/conf/app-agent-config.xml diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 5cca4d477c..94a0be2841 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -28,6 +28,13 @@ class AppDynamicsAgent < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile download_zip(false, @droplet.sandbox, 'AppDynamics Agent') + + # acessor for resources dir through @droplet? + resources_dir = Pathname.new(File.expand_path('../../../resources', __dir__)).freeze + default_conf_dir = resources_dir + @droplet.component_id + 'defaults' + + copy_appd_default_configuration(default_conf_dir) + @droplet.copy_resources end @@ -104,6 +111,18 @@ def tier_name(java_opts, credentials) java_opts.add_system_property('appdynamics.agent.tierName', name.to_s) end + # Copy default configuration present in resources folder of app_dynamics_agent ver* directories present in sandbox + # + # @param [Pathname] default_conf_dir the 'defaults' directory present in app_dynamics_agent resources. + # @return [Void] + def copy_appd_default_configuration(default_conf_dir) + if default_conf_dir.exist? + Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| + FileUtils.cp_r"#{default_conf_dir}/.", target_directory + end + end + end + end end diff --git a/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml b/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml new file mode 100644 index 0000000000..80c3eb9e66 --- /dev/null +++ b/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml @@ -0,0 +1,702 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.singularity.ee.agent.appagent.kernel.DynamicServiceManager + + + + + + + + + + BCIEngine,TransactionMonitoringService,SnapshotService + + + + + + + + BCIEngine + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BCIEngine + + + + + + + + + + + + + + + + + + + + + + + + + + + + BCIEngine,SnapshotService + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JMXService + + + BCIEngine + + + + + + + + + + + + + + + + + + + + + + + + + + BCIEngine + + + + + + + + + + + + + + + + + + + + + + + BCIEngine + + + + + TransactionMonitoringService + + + + + + + + + + + + + + From 11a3accdd6d78fa6b5113e7617dea9b5744360df Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 12 Mar 2019 11:26:20 -0700 Subject: [PATCH 497/812] Polishing [resolves #684] Signed-off-by: Ben Hale --- .../framework/app_dynamics_agent.rb | 18 ++--- .../defaults/conf/app-agent-config.xml | 69 +++++++++++++------ 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 94a0be2841..78b4e43ac6 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -28,20 +28,20 @@ class AppDynamicsAgent < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile download_zip(false, @droplet.sandbox, 'AppDynamics Agent') - - # acessor for resources dir through @droplet? + + # acessor for resources dir through @droplet? resources_dir = Pathname.new(File.expand_path('../../../resources', __dir__)).freeze default_conf_dir = resources_dir + @droplet.component_id + 'defaults' - + copy_appd_default_configuration(default_conf_dir) - + @droplet.copy_resources end # (see JavaBuildpack::Component::BaseComponent#release) def release credentials = @application.services.find_service(FILTER, 'host-name')['credentials'] - java_opts = @droplet.java_opts + java_opts = @droplet.java_opts java_opts.add_javaagent(@droplet.sandbox + 'javaagent.jar') application_name java_opts, credentials @@ -116,10 +116,10 @@ def tier_name(java_opts, credentials) # @param [Pathname] default_conf_dir the 'defaults' directory present in app_dynamics_agent resources. # @return [Void] def copy_appd_default_configuration(default_conf_dir) - if default_conf_dir.exist? - Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| - FileUtils.cp_r"#{default_conf_dir}/.", target_directory - end + return unless default_conf_dir.exist? + + Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| + FileUtils.cp_r "#{default_conf_dir}/.", target_directory end end diff --git a/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml b/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml index 80c3eb9e66..09d28bb80f 100644 --- a/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml +++ b/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml @@ -91,10 +91,10 @@ - - + + @@ -179,6 +179,7 @@ + - - - + @@ -316,7 +317,7 @@ instance: getter-chain eg. getName().toString() action - type: announcement, execution, suppression + type: announcement, execution, suppression, cancellation, shutdown token: announcement: this - invoked object @@ -324,6 +325,11 @@ execution: this - invoked object - argument (first argument is 0) + cancellation: + this - invoked object + - argument (first argument is 0) + shutdown: + return - returned object --> @@ -344,6 +350,22 @@ + + + + + + + + + + + + + + + + @@ -362,43 +384,48 @@ - + - + - + - + + + + + + - + - + - + - + @@ -408,12 +435,12 @@ - + - + @@ -675,7 +702,7 @@ - + BCIEngine @@ -698,5 +725,5 @@ - --> + --> From 5c7fbfed243e8fe345f29a0b2e6e59a180f742bd Mon Sep 17 00:00:00 2001 From: Luis Garcia Date: Thu, 14 Feb 2019 16:07:56 +0100 Subject: [PATCH 498/812] Updates to the Dynatrace extension - Set log stream to stdout by default. - Set location from service credentials [#692] Signed-off-by: Ben Hale --- .../framework/dynatrace_one_agent.rb | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 4ef267a15e..c8d1d7b81b 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -90,14 +90,20 @@ def supports? DT_TENANTTOKEN = 'DT_TENANTTOKEN' + DT_LOGSTREAM = 'DT_LOGSTREAM' + + DT_LOCATION = 'DT_LOCATION' + ENVIRONMENTID = 'environmentid' FILTER = /dynatrace/.freeze + LOCATION = 'location' + SKIP_ERRORS = 'skiperrors' - private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_TENANT, - :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :SKIP_ERRORS + private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_LOCATION, :DT_LOGSTREAM, + :DT_TENANT, :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :LOCATION, :SKIP_ERRORS def agent_download_url download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ @@ -141,6 +147,8 @@ def dynatrace_environment_variables(manifest) .add_environment_variable(DT_CONNECTION_POINT, endpoints(manifest)) environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) unless application_id? + environment_variables.add_environment_variable(DT_LOCATION, credentials[LOCATION]) if location? + environment_variables.add_environment_variable(DT_LOGSTREAM, "stdout") unless logstream? end def endpoints(manifest) @@ -161,6 +169,14 @@ def expand(file) end end + def location? + credentials.key?(LOCATION) + end + + def logstream? + @application.environment.key?(DT_LOGSTREAM) + end + def skip_errors? credentials[SKIP_ERRORS].to_b end From d6844d0112a0d43d0579c470118c0cf8fa7442e5 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 12 Mar 2019 11:35:38 -0700 Subject: [PATCH 499/812] Polishing [resolves #692] Signed-off-by: Ben Hale --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index c8d1d7b81b..57d4031b34 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -148,7 +148,7 @@ def dynatrace_environment_variables(manifest) environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) unless application_id? environment_variables.add_environment_variable(DT_LOCATION, credentials[LOCATION]) if location? - environment_variables.add_environment_variable(DT_LOGSTREAM, "stdout") unless logstream? + environment_variables.add_environment_variable(DT_LOGSTREAM, 'stdout') unless logstream? end def endpoints(manifest) From b690290868bc251b76f3bdef76877fa247504fd5 Mon Sep 17 00:00:00 2001 From: rbamberger <45032044+rbamberger@users.noreply.github.com> Date: Wed, 21 Nov 2018 09:21:56 +0100 Subject: [PATCH 500/812] Added Java VM Option to turn Class Data Sharing Off [resolves #653] Signed-off-by: Ben Hale --- lib/java_buildpack/framework/dynatrace_appmon_agent.rb | 1 + lib/java_buildpack/framework/dynatrace_one_agent.rb | 1 + spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb | 3 ++- spec/java_buildpack/framework/dynatrace_one_agent_spec.rb | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb index 5f0c657d8c..b1f65f10ff 100644 --- a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb @@ -36,6 +36,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts.add_agentpath_with_props(agent_path, name: agent_name, server: server) + @droplet.java_opts.add_preformatted_options('-Xshare:off') end protected diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 57d4031b34..82043fdffa 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -65,6 +65,7 @@ def release manifest = agent_manifest @droplet.java_opts.add_agentpath(agent_path(manifest)) + @droplet.java_opts.add_preformatted_options('-Xshare:off') dynatrace_environment_variables(manifest) end diff --git a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb index dc1118b5fc..24b7e791ba 100644 --- a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb @@ -50,10 +50,11 @@ expect(sandbox + 'agent/lib64/libdtagent.so').to exist end - it 'updates JAVA_OPTS' do + it 'updates JAVA_OPTS and share set to off' do component.release expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_appmon_agent/agent/lib64/'\ 'libdtagent.so=name=test-application-name_Monitoring,server=test-host-name') + expect(java_opts).to include('-Xshare:off') end context do diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index a88df6e04e..bbcba2ec44 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -54,13 +54,14 @@ expect(sandbox + 'manifest.json').to exist end - it 'updates JAVA_OPTS with agent loader', + it 'updates JAVA_OPTS with agent loader and share set to off', app_fixture: 'framework_dynatrace_one_agent' do component.release expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_one_agent/agent/lib64/' \ 'liboneagentloader.so') + expect(java_opts).to include('-Xshare:off') end it 'updates environment variables', From 8178aa59d6d05bf53edf780582fbb37fe518a6a8 Mon Sep 17 00:00:00 2001 From: Pavan Krishna Date: Tue, 12 Mar 2019 14:04:47 -0700 Subject: [PATCH 501/812] use empty string not * to mask all env variables. --- resources/app_dynamics_agent/defaults/conf/app-agent-config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml b/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml index 09d28bb80f..b09a260565 100644 --- a/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml +++ b/resources/app_dynamics_agent/defaults/conf/app-agent-config.xml @@ -94,7 +94,7 @@ + match-pattern=""/> From eec88ec5ff4999cc1a2b0b5a33b6b388e6ce78bc Mon Sep 17 00:00:00 2001 From: kenmac Date: Tue, 15 Jan 2019 10:33:47 -0500 Subject: [PATCH 502/812] Elastic APM This change adds support for the Elastic APM agent. [#696] Signed-off-by: Ben Hale --- README.md | 1 + config/components.yml | 1 + config/elastic_apm_agent.yml | 19 ++++ docs/framework-elastic_apm_agent.md | 69 +++++++++++++ .../framework/elastic_apm_agent.rb | 99 +++++++++++++++++++ rakelib/versions_task.rb | 1 + spec/fixtures/stub-elastic-apm-agent.jar | 0 .../framework/elastic_apm_agent_spec.rb | 95 ++++++++++++++++++ 8 files changed, 285 insertions(+) create mode 100644 config/elastic_apm_agent.yml create mode 100644 docs/framework-elastic_apm_agent.md create mode 100644 lib/java_buildpack/framework/elastic_apm_agent.rb create mode 100644 spec/fixtures/stub-elastic-apm-agent.jar create mode 100644 spec/java_buildpack/framework/elastic_apm_agent_spec.rb diff --git a/README.md b/README.md index 91b9a353ba..6e213d4e3e 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ The buildpack supports extension through the use of Git repository forking. The * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) * [Dyadic EKM Security Provider](docs/framework-dyadic_ekm_security_provider.md) ([Configuration](docs/framework-dyadic_ekm_security_provider.md#configuration)) * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) + * [Elastic APM Agent](docs/framework-elastic_apm_agent.md) ([Configuration](docs/framework-elastic_apm_agent.md#configuration)) * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) * [Google Stackdriver Debugger](docs/framework-google_stackdriver_debugger.md) ([Configuration](docs/framework-google_stackdriver_debugger.md#configuration)) * [Google Stackdriver Profiler](docs/framework-google_stackdriver_profiler.md) ([Configuration](docs/framework-google_stackdriver_profiler.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 33fea9d51b..99bd44226a 100644 --- a/config/components.yml +++ b/config/components.yml @@ -51,6 +51,7 @@ frameworks: - "JavaBuildpack::Framework::DyadicEkmSecurityProvider" - "JavaBuildpack::Framework::DynatraceAppmonAgent" - "JavaBuildpack::Framework::DynatraceOneAgent" + - "JavaBuildpack::Framework::ElasticApmAgent" - "JavaBuildpack::Framework::GoogleStackdriverDebugger" - "JavaBuildpack::Framework::GoogleStackdriverProfiler" - "JavaBuildpack::Framework::IntroscopeAgent" diff --git a/config/elastic_apm_agent.yml b/config/elastic_apm_agent.yml new file mode 100644 index 0000000000..c41ace3ffa --- /dev/null +++ b/config/elastic_apm_agent.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Elastic Apm Agent framework +--- +version: 1.+ +repository_root: https://raw.githubusercontent.com/elastic/apm-agent-java/master/cloudfoundry diff --git a/docs/framework-elastic_apm_agent.md b/docs/framework-elastic_apm_agent.md new file mode 100644 index 0000000000..c2975c8682 --- /dev/null +++ b/docs/framework-elastic_apm_agent.md @@ -0,0 +1,69 @@ +# Elastic APM Agent Framework + +The Elastic APM Agent Framework causes an application to be automatically configured to work with [Elastic APM][]. + +
+ + + + + + + +
Detection CriterionExistence of a single bound Elastic APM service. The existence of an Elastic APM service defined by the VCAP_SERVICES payload containing a service name, label or tag with elasticapm or elastic-apm as a substring. +
Tagselastic-apm-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +For more information regarding setup and configuration, please refer to the [Elastic APM with Pivotal Cloud Foundry tutorial][pivotal]. + +## User-Provided Service +When binding Elastic APM using a user-provided service, it must have name or tag with `elasticapm` or `elastic-apm` in it. The credential payload can contain the following entries. + +| Name | Description +| ---- | ----------- +| `server_urls` | The URLs for the Elastic APM Server. They must be fully qualified, including protocol (http or https) and port. +| `secret_token` (Optional)| This string is used to ensure that only your agents can send data to your APM server. Both the agents and the APM server have to be configured with the same secret token. Use if APM Server requires a token. +| `***` (Optional) | Any additional entries will be applied as a system property appended to `-Delastic.apm.` to allow full configuration of the agent. See [Configuration of Elastic Agent][]. + + +### Creating an Elastic APM USer Provided Service +Users must provide their own Elastic APM service. A user-provided Elastic APM service must have a name or tag with `elastic-apm` or `elasticapm` in it so that the Elastic APM Agent Framework will automatically configure the application to work with the service. + +Example of a minimal configuration: + +``` +cf cups my-elastic-apm-service -p '{"server_urls":"https://my-apm-server:8200","secret_token":"my-secret-token"}' +``` + +Example of a configuration with additional configuration parameters: + +``` +cf cups my-elastic-apm-service -p '{"server_urls":"https://my-apm-server:8200","secret_token":"","server_timeout":"10s","environment":"production"}' +``` + +Bind your application to the service using: + +`cf bind-service my-app-name my-elastic-apm-service` + +or use the `services` block in the application manifest file. + + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/elastic_apm_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `service_name` | This can be overridden by a `service_name` entry in the credentials payload. If neither are supplied the default is the application_name as specified by Cloud Foundry. +| `repository_root` | The URL of the Elastic APM repository index ([details][repositories]). +| `version` | The version of Elastic APM to use. Candidate versions can be found in [this listing][]. + + +[Configuration and Extension]: ../README.md#configuration-and-extension +[`config/elastic_apm_agent.yml`]: ../config/elastic_apm_agent.yml +[Elastic APM]: https://www.elastic.co/guide/en/apm/agent/java/current/index.html +[repositories]: extending-repositories.md +[this listing]: https://raw.githubusercontent.com/elastic/apm-agent-java/master/cloudfoundry/index.yml +[version syntax]: extending-repositories.md#version-syntax-and-ordering +[Configuration of Elastic Agent]: https://www.elastic.co/guide/en/apm/agent/java/current/configuration.html diff --git a/lib/java_buildpack/framework/elastic_apm_agent.rb b/lib/java_buildpack/framework/elastic_apm_agent.rb new file mode 100644 index 0000000000..2c09a92b43 --- /dev/null +++ b/lib/java_buildpack/framework/elastic_apm_agent.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Elastic APM support. + class ElasticApmAgent < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + @droplet.copy_resources + end + + # Modifies the application's runtime configuration. The component is expected to transform members of the + # +context+ # (e.g. +@java_home+, +@java_opts+, etc.) in whatever way is necessary to support the function of the + # component. + # + # Container components are also expected to create the command required to run the application. These components + # are expected to read the +context+ values and take them into account when creating the command. + # + # @return [void, String] components other than containers and JREs are not expected to return any value. + # Container and JRE components are expected to return a command required to run the + # application. + # (see JavaBuildpack::Component::BaseComponent#release) + def release + credentials = @application.services.find_service(FILTER, [SERVER_URL, SECRET_TOKEN])['credentials'] + java_opts = @droplet.java_opts + configuration = {} + + apply_configuration(credentials, configuration) + apply_user_configuration(credentials, configuration) + write_java_opts(java_opts, configuration) + + java_opts.add_javaagent(@droplet.sandbox + jar_name) + .add_system_property('elastic.apm.home', @droplet.sandbox) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, [SERVER_URL, SECRET_TOKEN] + end + + private + + FILTER = /elastic[-]?apm/ + + BASE_KEY = 'elastic.apm.' + + SERVER_URL = 'server_urls' + + SECRET_TOKEN = "secret_token" + + SERVICE_NAME = 'service_name' + + private_constant :FILTER, :SERVER_URL, :BASE_KEY, :SECRET_TOKEN + + def apply_configuration(credentials, configuration) + configuration['log_file_name'] = 'STDOUT' + configuration[SERVER_URL] = credentials[SERVER_URL] + configuration[SECRET_TOKEN] = credentials[SECRET_TOKEN] + configuration[SERVICE_NAME] = @application.details['application_name'] + end + + def apply_user_configuration(credentials, configuration) + credentials.each do |key, value| + configuration[key] = value + end + end + + def write_java_opts(java_opts, configuration) + configuration.each do |key, value| + java_opts.add_system_property("elastic.apm.#{key}", value) + end + end + + end + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 4065a0e1df..878409ed69 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -63,6 +63,7 @@ def initialize 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', 'dynatrace_one_agent' => 'Dynatrace OneAgent', + 'elastic_apm_agent' => 'Elastic APM Agent', 'geode_store' => 'Geode Tomcat Session Store', 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', diff --git a/spec/fixtures/stub-elastic-apm-agent.jar b/spec/fixtures/stub-elastic-apm-agent.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/elastic_apm_agent_spec.rb b/spec/java_buildpack/framework/elastic_apm_agent_spec.rb new file mode 100644 index 0000000000..0014048ef8 --- /dev/null +++ b/spec/java_buildpack/framework/elastic_apm_agent_spec.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/new_relic_agent' +require 'java_buildpack/util/tokenized_version' + +describe JavaBuildpack::Framework::ElasticApmAgent do + include_context 'with component help' + + it 'does not detect without elastic-apm-n/a service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?).with(/elastic[-]?apm/, %w[secret_token secret_token]).and_return(true) + end + + it 'detects with elastic-apm-n/a service' do + expect(component.detect).to eq("elastic-apm-agent=#{version}") + end + + it 'downloads elastic-apm agent JAR', + cache_fixture: 'stub-elastic-apm-agent.jar' do + + component.compile + + expect(sandbox + "elastic_apm_agent-#{version}.jar").to exist + end + + it 'copies resources', + cache_fixture: 'stub-elastic-apm-agent.jar' do + + component.compile + + expect(sandbox + 'elastic.yml').to exist + end + + it 'updates JAVA_OPTS' do + allow(services).to receive(:find_service).and_return('credentials' => { 'secret_token' => 'secret_token' }) + allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.4.0')) + + component.release + + expect(java_opts).to include("-javaagent:$PWD/.java-buildpack/elastic_apm_agent/elastic_apm_agent-#{version}.jar") + expect(java_opts).to include('-Delastic.apm.home=$PWD/.java-buildpack/elastic_apm_agent') + expect(java_opts).to include('-Delastic.apm.config.secret_token=test-license-key') + expect(java_opts).to include('-Delastic.apm.config.app_name=test-application-name') + expect(java_opts).to include('-Delastic.apm.config.log_file_name=STDOUT') + end + + it 'updates JAVA_OPTS with additional options' do + allow(services).to receive(:find_service).and_return('credentials' => { 'secret_token' => 'test-secret_token', + 'server_urls' => 'different-serverurl', + 'service_name' => 'different-name', + 'foo' => 'bar' }) + allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.4.0')) + + component.release + + expect(java_opts).to include('-Dnelastic.apm.config.secret_token=test-secret_token') + expect(java_opts).to include('-Delastic.apm.server_urls=different-serverurl') + expect(java_opts).to include('-Delastic.apm.service_name=different-name') + expect(java_opts).to include('-Delastic.apm.foo=bar') + end + + it 'updates JAVA_OPTS on Java 8' do + allow(services).to receive(:find_service).and_return('credentials' => { 'secret_token' => 'test-license-key' }) + allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.4.0')) + + component.release + + expect(java_opts).to include('-Delastic.apm.enable.java.8=true') + end + + end + +end From a8ed5d04630cf2433f9840525450b28f4362f0e4 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 1 Apr 2019 15:51:13 -0700 Subject: [PATCH 503/812] Polishing [resolves #696] Signed-off-by: Ben Hale --- docs/framework-elastic_apm_agent.md | 6 ++-- .../framework/elastic_apm_agent.rb | 17 +++++---- .../framework/elastic_apm_agent_spec.rb | 35 +++++-------------- 3 files changed, 19 insertions(+), 39 deletions(-) diff --git a/docs/framework-elastic_apm_agent.md b/docs/framework-elastic_apm_agent.md index c2975c8682..8d1cf11ad2 100644 --- a/docs/framework-elastic_apm_agent.md +++ b/docs/framework-elastic_apm_agent.md @@ -5,7 +5,7 @@ The Elastic APM Agent Framework causes an application to be automatically config - @@ -14,8 +14,6 @@ The Elastic APM Agent Framework causes an application to be automatically config
Detection CriterionExistence of a single bound Elastic APM service. The existence of an Elastic APM service defined by the VCAP_SERVICES payload containing a service name, label or tag with elasticapm or elastic-apm as a substring. + Existence of a single bound Elastic APM service. The existence of an Elastic APM service defined by the VCAP_SERVICES payload containing a service name, label or tag with elastic-apm as a substring.
Tags
Tags are printed to standard output by the buildpack detect script -For more information regarding setup and configuration, please refer to the [Elastic APM with Pivotal Cloud Foundry tutorial][pivotal]. - ## User-Provided Service When binding Elastic APM using a user-provided service, it must have name or tag with `elasticapm` or `elastic-apm` in it. The credential payload can contain the following entries. @@ -27,7 +25,7 @@ When binding Elastic APM using a user-provided service, it must have name or tag ### Creating an Elastic APM USer Provided Service -Users must provide their own Elastic APM service. A user-provided Elastic APM service must have a name or tag with `elastic-apm` or `elasticapm` in it so that the Elastic APM Agent Framework will automatically configure the application to work with the service. +Users must provide their own Elastic APM service. A user-provided Elastic APM service must have a name or tag with `elastic-apm` in it so that the Elastic APM Agent Framework will automatically configure the application to work with the service. Example of a minimal configuration: diff --git a/lib/java_buildpack/framework/elastic_apm_agent.rb b/lib/java_buildpack/framework/elastic_apm_agent.rb index 2c09a92b43..6199385c3b 100644 --- a/lib/java_buildpack/framework/elastic_apm_agent.rb +++ b/lib/java_buildpack/framework/elastic_apm_agent.rb @@ -27,7 +27,6 @@ class ElasticApmAgent < JavaBuildpack::Component::VersionedDependencyComponent # (see JavaBuildpack::Component::BaseComponent#compile) def compile download_jar - @droplet.copy_resources end # Modifies the application's runtime configuration. The component is expected to transform members of the @@ -42,7 +41,7 @@ def compile # application. # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, [SERVER_URL, SECRET_TOKEN])['credentials'] + credentials = @application.services.find_service(FILTER, [SERVER_URLS, SECRET_TOKEN])['credentials'] java_opts = @droplet.java_opts configuration = {} @@ -51,33 +50,33 @@ def release write_java_opts(java_opts, configuration) java_opts.add_javaagent(@droplet.sandbox + jar_name) - .add_system_property('elastic.apm.home', @droplet.sandbox) + .add_system_property('elastic.apm.home', @droplet.sandbox) end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, [SERVER_URL, SECRET_TOKEN] + @application.services.one_service? FILTER, [SERVER_URLS, SECRET_TOKEN] end private - FILTER = /elastic[-]?apm/ + FILTER = /elastic-apm/.freeze BASE_KEY = 'elastic.apm.' - SERVER_URL = 'server_urls' + SERVER_URLS = 'server_urls' - SECRET_TOKEN = "secret_token" + SECRET_TOKEN = 'secret_token' SERVICE_NAME = 'service_name' - private_constant :FILTER, :SERVER_URL, :BASE_KEY, :SECRET_TOKEN + private_constant :FILTER, :SERVER_URLS, :BASE_KEY, :SECRET_TOKEN def apply_configuration(credentials, configuration) configuration['log_file_name'] = 'STDOUT' - configuration[SERVER_URL] = credentials[SERVER_URL] + configuration[SERVER_URLS] = credentials[SERVER_URLS] configuration[SECRET_TOKEN] = credentials[SECRET_TOKEN] configuration[SERVICE_NAME] = @application.details['application_name'] end diff --git a/spec/java_buildpack/framework/elastic_apm_agent_spec.rb b/spec/java_buildpack/framework/elastic_apm_agent_spec.rb index 0014048ef8..ba5ad915ec 100644 --- a/spec/java_buildpack/framework/elastic_apm_agent_spec.rb +++ b/spec/java_buildpack/framework/elastic_apm_agent_spec.rb @@ -17,7 +17,7 @@ require 'spec_helper' require 'component_helper' -require 'java_buildpack/framework/new_relic_agent' +require 'java_buildpack/framework/elastic_apm_agent' require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Framework::ElasticApmAgent do @@ -30,7 +30,7 @@ context do before do - allow(services).to receive(:one_service?).with(/elastic[-]?apm/, %w[secret_token secret_token]).and_return(true) + allow(services).to receive(:one_service?).with(/elastic-apm/, %w[server_urls secret_token]).and_return(true) end it 'detects with elastic-apm-n/a service' do @@ -45,25 +45,18 @@ expect(sandbox + "elastic_apm_agent-#{version}.jar").to exist end - it 'copies resources', - cache_fixture: 'stub-elastic-apm-agent.jar' do - - component.compile - - expect(sandbox + 'elastic.yml').to exist - end - it 'updates JAVA_OPTS' do - allow(services).to receive(:find_service).and_return('credentials' => { 'secret_token' => 'secret_token' }) - allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.4.0')) + allow(services).to receive(:find_service).and_return('credentials' => { 'server_urls' => 'serverurl', + 'secret_token' => 'secret_token' }) component.release expect(java_opts).to include("-javaagent:$PWD/.java-buildpack/elastic_apm_agent/elastic_apm_agent-#{version}.jar") expect(java_opts).to include('-Delastic.apm.home=$PWD/.java-buildpack/elastic_apm_agent') - expect(java_opts).to include('-Delastic.apm.config.secret_token=test-license-key') - expect(java_opts).to include('-Delastic.apm.config.app_name=test-application-name') - expect(java_opts).to include('-Delastic.apm.config.log_file_name=STDOUT') + expect(java_opts).to include('-Delastic.apm.server_urls=serverurl') + expect(java_opts).to include('-Delastic.apm.secret_token=secret_token') + expect(java_opts).to include('-Delastic.apm.service_name=test-application-name') + expect(java_opts).to include('-Delastic.apm.log_file_name=STDOUT') end it 'updates JAVA_OPTS with additional options' do @@ -71,25 +64,15 @@ 'server_urls' => 'different-serverurl', 'service_name' => 'different-name', 'foo' => 'bar' }) - allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.4.0')) component.release - expect(java_opts).to include('-Dnelastic.apm.config.secret_token=test-secret_token') + expect(java_opts).to include('-Delastic.apm.secret_token=test-secret_token') expect(java_opts).to include('-Delastic.apm.server_urls=different-serverurl') expect(java_opts).to include('-Delastic.apm.service_name=different-name') expect(java_opts).to include('-Delastic.apm.foo=bar') end - it 'updates JAVA_OPTS on Java 8' do - allow(services).to receive(:find_service).and_return('credentials' => { 'secret_token' => 'test-license-key' }) - allow(java_home).to receive(:java_8_or_later?).and_return(JavaBuildpack::Util::TokenizedVersion.new('1.4.0')) - - component.release - - expect(java_opts).to include('-Delastic.apm.enable.java.8=true') - end - end end From cd849e8ba7d385946f4e99233c2525188fcb6e20 Mon Sep 17 00:00:00 2001 From: Owen Farrell Date: Fri, 15 Mar 2019 12:31:18 -0400 Subject: [PATCH 504/812] Added default_server_name to Contrast Security Framework [resolves #702] Signed-off-by: Ben Hale --- config/contrast_security_agent.yml | 1 + docs/framework-contrast_security_agent.md | 1 + .../framework/contrast_security_agent.rb | 10 ++++++++++ .../framework/contrast_security_agent_spec.rb | 10 ++++++++++ 4 files changed, 22 insertions(+) diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index e3fd6bf7db..d6fdfd9f8d 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -16,4 +16,5 @@ # Configuration for the ContrastSecurity framework --- version: 3.+ +default_server_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name + \":$CF_INSTANCE_INDEX\"") repository_root: https://artifacts.contrastsecurity.com/agents/java diff --git a/docs/framework-contrast_security_agent.md b/docs/framework-contrast_security_agent.md index ab6e5d4ea0..efd8fed8e3 100644 --- a/docs/framework-contrast_security_agent.md +++ b/docs/framework-contrast_security_agent.md @@ -27,6 +27,7 @@ The framework can be configured by modifying the [`config/contrast_security_agen | Name | Description | ---- | ----------- | `repository_root` | The URL of the Contrast Security repository index ([details][repositories]). +| `default_server_name` | The default server name for this application in the Contrast dashboard. The default value is an expression that will be evaluated based on the `space_name`, `application_name`, and `instance_index` of the application. | | `version` | The version of Contrast Security to use. Candidate versions can be found in [this listing][]. [Contrast Security]: https://www.contrastsecurity.com diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index f2fc4ab379..d79145fbfa 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -40,6 +40,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts.add_system_property('contrast.override.appname', application_name) unless appname_exist? + @droplet.java_opts.add_system_property('contrast.server', server_name) unless server_exist? @droplet.java_opts .add_system_property('contrast.dir', '$TMPDIR') @@ -118,6 +119,15 @@ def contrast_config @droplet.sandbox + 'contrast.config' end + def server_exist? + @droplet.java_opts.any? { |java_opt| java_opt =~ /contrast.server/ } + end + + def server_name + @configuration['default_server_name'] || + "#{@application.details['space_name']}:#{@application.details['application_name']}:$CF_INSTANCE_INDEX" + end + def short_version "#{@version[0]}.#{@version[1]}.#{@version[2]}" end diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb index d7a3287a80..9b6ae71819 100644 --- a/spec/java_buildpack/framework/contrast_security_agent_spec.rb +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -77,6 +77,7 @@ '=$PWD/.java-buildpack/contrast_security_agent/contrast.config') expect(java_opts).to include('-Dcontrast.dir=$TMPDIR') expect(java_opts).to include('-Dcontrast.override.appname=test-application-name') + expect(java_opts).to include('-Dcontrast.server=test-space-name:test-application-name:$CF_INSTANCE_INDEX') end it 'created contrast.config', @@ -95,6 +96,15 @@ expect(java_opts).not_to include('-Dcontrast.override.appname=test-application-name') end + it 'does not override server if there is an existing server' do + java_opts.add_system_property('contrast.server', 'NAME_ALREADY_OVERRIDDEN') + + component.release + + expect(java_opts).to include('-Dcontrast.server=NAME_ALREADY_OVERRIDDEN') + expect(java_opts).not_to include('-Dcontrast.server=test-space-name:test-application-name:$CF_INSTANCE_INDEX') + end + end end From 3f4eee26755304b95e3a17be50b95ec48c594b55 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 1 Apr 2019 15:59:03 -0700 Subject: [PATCH 505/812] Java 12 This change adds support for packaging Java 12. [resolves #703] Signed-off-by: Ben Hale --- rakelib/dependency_cache_task.rb | 7 +++++++ rakelib/versions_task.rb | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index e0c7ed4412..7b6f7633b6 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -130,6 +130,13 @@ def configurations(component_id, configuration, sub_component_id = nil) configurations << c1 end + if component_id == 'open_jdk_jre' && sub_component_id == 'jre' + c1 = configuration.clone + c1['version'] = '12.+' + + configurations << c1 + end + configurations << configuration else configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 878409ed69..eebfc338cd 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -73,6 +73,7 @@ def initialize 'jprofiler_profiler' => 'JProfiler Profiler', 'jre' => 'OpenJDK JRE', 'jre-11' => 'OpenJDK JRE 11', + 'jre-12' => 'OpenJDK JRE 12', 'jrebel_agent' => 'JRebel Agent', 'jvmkill_agent' => 'jvmkill Agent', 'lifecycle_support' => 'Tomcat Lifecycle Support', @@ -165,6 +166,13 @@ def configurations(component_id, configuration, sub_component_id = nil) configurations << c1 end + if component_id == 'open_jdk_jre' && sub_component_id == 'jre' + c1 = configuration.clone + c1['sub_component_id'] = 'jre-12' + c1['version'] = '12.+' + + configurations << c1 + end configurations << configuration else configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } From 4d165a3977dcad15359b7ac8e391d87bf5b97d12 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 Apr 2019 14:31:25 -0700 Subject: [PATCH 506/812] Polishing Signed-off-by: Ben Hale --- ci/auto-merge.sh | 2 +- ci/auto-merge.yml | 2 +- ci/create-release.sh | 2 +- ci/package-test.sh | 2 +- ci/package-test.yml | 2 +- ci/unit-test.sh | 2 +- ci/unit-test.yml | 2 +- ci/versions-json.sh | 2 +- ci/versions-json.yml | 2 +- ci/versions-markdown.sh | 2 +- ci/versions-markdown.yml | 2 +- ci/versions-yaml.sh | 2 +- ci/versions-yaml.yml | 2 +- ci/versions.sh | 2 +- ci/versions.yml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ci/auto-merge.sh b/ci/auto-merge.sh index 1bba3cb58d..b60c842e3c 100755 --- a/ci/auto-merge.sh +++ b/ci/auto-merge.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e -u +set -euo pipefail pushd upstream COMMIT=$(git rev-parse HEAD) diff --git a/ci/auto-merge.yml b/ci/auto-merge.yml index 79540a9322..eed658e8de 100644 --- a/ci/auto-merge.yml +++ b/ci/auto-merge.yml @@ -16,7 +16,7 @@ platform: linux image_resource: - type: docker-image + type: registry-image source: repository: cfje/java-buildpack diff --git a/ci/create-release.sh b/ci/create-release.sh index 943ddf8931..e41f8f2754 100755 --- a/ci/create-release.sh +++ b/ci/create-release.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -set -e -u +set -euo pipefail RELEASE=$1 diff --git a/ci/package-test.sh b/ci/package-test.sh index 14e3e11198..3731327739 100755 --- a/ci/package-test.sh +++ b/ci/package-test.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e -u +set -euo pipefail export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 diff --git a/ci/package-test.yml b/ci/package-test.yml index dc8b91e273..fb2800e729 100644 --- a/ci/package-test.yml +++ b/ci/package-test.yml @@ -16,7 +16,7 @@ platform: linux image_resource: - type: docker-image + type: registry-image source: repository: cfje/java-buildpack diff --git a/ci/unit-test.sh b/ci/unit-test.sh index 29e76d676b..df68193a40 100755 --- a/ci/unit-test.sh +++ b/ci/unit-test.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e -u +set -euo pipefail export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 diff --git a/ci/unit-test.yml b/ci/unit-test.yml index cbd505426c..bf6d15e328 100644 --- a/ci/unit-test.yml +++ b/ci/unit-test.yml @@ -16,7 +16,7 @@ platform: linux image_resource: - type: docker-image + type: registry-image source: repository: cfje/java-buildpack diff --git a/ci/versions-json.sh b/ci/versions-json.sh index c03eb37b58..b8572ae50b 100755 --- a/ci/versions-json.sh +++ b/ci/versions-json.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e -u +set -euo pipefail export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 diff --git a/ci/versions-json.yml b/ci/versions-json.yml index 1a26902879..227f62b451 100644 --- a/ci/versions-json.yml +++ b/ci/versions-json.yml @@ -16,7 +16,7 @@ platform: linux image_resource: - type: docker-image + type: registry-image source: repository: cfje/java-buildpack diff --git a/ci/versions-markdown.sh b/ci/versions-markdown.sh index 4fb3958e9b..7b737cb001 100755 --- a/ci/versions-markdown.sh +++ b/ci/versions-markdown.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e -u +set -euo pipefail export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 diff --git a/ci/versions-markdown.yml b/ci/versions-markdown.yml index 1807c333d0..cc3a5262de 100644 --- a/ci/versions-markdown.yml +++ b/ci/versions-markdown.yml @@ -16,7 +16,7 @@ platform: linux image_resource: - type: docker-image + type: registry-image source: repository: cfje/java-buildpack diff --git a/ci/versions-yaml.sh b/ci/versions-yaml.sh index 2da7d35e3e..38c0445efd 100755 --- a/ci/versions-yaml.sh +++ b/ci/versions-yaml.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e -u +set -euo pipefail export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 diff --git a/ci/versions-yaml.yml b/ci/versions-yaml.yml index 46bdf6f766..e6699ae557 100644 --- a/ci/versions-yaml.yml +++ b/ci/versions-yaml.yml @@ -16,7 +16,7 @@ platform: linux image_resource: - type: docker-image + type: registry-image source: repository: cfje/java-buildpack diff --git a/ci/versions.sh b/ci/versions.sh index d7548a555c..982ce74cef 100755 --- a/ci/versions.sh +++ b/ci/versions.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e -u +set -euo pipefail export GEM_HOME=$PWD/gems export LANG=en_US.UTF-8 diff --git a/ci/versions.yml b/ci/versions.yml index eb9e9ee824..f644e51e40 100644 --- a/ci/versions.yml +++ b/ci/versions.yml @@ -16,7 +16,7 @@ platform: linux image_resource: - type: docker-image + type: registry-image source: repository: cfje/java-buildpack From e68e06117f772fcf276cdc4c5a21fe9f276bc472 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 Apr 2019 15:40:49 -0700 Subject: [PATCH 507/812] Polishing Signed-off-by: Ben Hale --- ci/create-release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/create-release.sh b/ci/create-release.sh index e41f8f2754..d3af657e41 100755 --- a/ci/create-release.sh +++ b/ci/create-release.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash set -euo pipefail From 7df9230954ec6d683b3cfaf72672a6ea45737c68 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 Apr 2019 16:52:18 -0700 Subject: [PATCH 508/812] Docker Build Improvements Signed-off-by: Ben Hale --- ci/{docker-image => }/Dockerfile | 2 +- ci/builder.yml | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) rename ci/{docker-image => }/Dockerfile (98%) create mode 100644 ci/builder.yml diff --git a/ci/docker-image/Dockerfile b/ci/Dockerfile similarity index 98% rename from ci/docker-image/Dockerfile rename to ci/Dockerfile index ca6e71f8ef..1f7049dc38 100644 --- a/ci/docker-image/Dockerfile +++ b/ci/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:trusty +FROM ubuntu:bionic RUN apt-get update && apt-get install -y \ build-essential \ diff --git a/ci/builder.yml b/ci/builder.yml new file mode 100644 index 0000000000..3f637a2ffa --- /dev/null +++ b/ci/builder.yml @@ -0,0 +1,22 @@ +--- +platform: linux + +image_resource: + type: registry-image + source: + repository: concourse/builder + +inputs: +- name: builder + +outputs: +- name: image + +caches: +- path: cache + +run: + path: build + +params: + CONTEXT: builder/ci From 4e7cbf4a675a11da5b4a31c755c8617da9d6e1f6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 Apr 2019 17:00:06 -0700 Subject: [PATCH 509/812] Add Bionic-needed package Signed-off-by: Ben Hale --- ci/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/Dockerfile b/ci/Dockerfile index 1f7049dc38..557bc06a13 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -6,6 +6,7 @@ RUN apt-get update && apt-get install -y \ git \ libssl-dev \ libreadline-dev \ + locales \ python \ zip \ zlib1g-dev \ From 4d9c3650815af63ed56e616329d39692c05c55e3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 Apr 2019 17:45:00 -0700 Subject: [PATCH 510/812] Remove Ruby 2.3 Signed-off-by: Ben Hale --- ci/Dockerfile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ci/Dockerfile b/ci/Dockerfile index 557bc06a13..2fdd1da0f8 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -31,14 +31,11 @@ RUN eval "$(rbenv init -)" \ && echo 'bundler' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ - && rbenv install 2.3.8 + && rbenv install 2.4.6 RUN eval "$(rbenv init -)" \ - && rbenv install 2.4.5 + && rbenv install 2.5.5 RUN eval "$(rbenv init -)" \ - && rbenv install 2.5.3 - -RUN eval "$(rbenv init -)" \ - && rbenv install 2.6.0 + && rbenv install 2.6.2 From 979276525c7fac38a4d6fcf0b2c76d9a25162cd7 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 Apr 2019 17:47:30 -0700 Subject: [PATCH 511/812] New minimum Ruby level Signed-off-by: Ben Hale --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index bc4abe86de..7bf4b6a8ae 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.3.8 +2.4.6 From 8ef27921df6f15648d10428d85925cfd3cffe23b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 Apr 2019 18:15:38 -0700 Subject: [PATCH 512/812] Rubocop required changes Signed-off-by: Ben Hale --- lib/java_buildpack/container/dist_zip_like.rb | 4 ++-- lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb | 2 +- lib/java_buildpack/repository/repository_index.rb | 2 +- rakelib/dependency_cache_task.rb | 2 +- rakelib/versions_task.rb | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 60ae1997c5..ea6bb34cad 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -103,9 +103,9 @@ def augment_classpath(content) def augment_classpath_content content = start_script(root).read - if content =~ PATTERN_CLASSPATH + if content.match? PATTERN_CLASSPATH augment_classpath content - elsif content =~ PATTERN_APP_CLASSPATH + elsif content.match? PATTERN_APP_CLASSPATH augment_app_classpath content end end diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 70c08f0b17..c81ef4265f 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -98,7 +98,7 @@ def memory_calculator end def memory_calculator_tar - platform = `uname -s` =~ /Darwin/ ? 'darwin' : 'linux' + platform = `uname -s`.match?(/Darwin/) ? 'darwin' : 'linux' @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{platform}" end diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index e80ba63c3f..a39e19f8aa 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -87,7 +87,7 @@ def platform if redhat_release.exist? tokens = redhat_release.read.match(/(\w+) (?:Linux )?release (\d+)/) "#{tokens[1].downcase}#{tokens[2]}" - elsif `uname -s` =~ /Darwin/ + elsif `uname -s`.match?(/Darwin/) 'mountainlion' elsif !`which lsb_release 2> /dev/null`.empty? `lsb_release -cs`.strip diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 7b6f7633b6..f63a462c1a 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -59,7 +59,7 @@ def initialize def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at raw.map(&block) - elsif raw[:uri] =~ pattern + elsif raw[:uri].match? pattern candidates.map do |candidate| dup = raw.clone dup[key] = candidate diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index eebfc338cd..7f7535c6a3 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -103,7 +103,7 @@ def initialize def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at raw.map(&block) - elsif raw[:uri] =~ pattern + elsif raw[:uri].match? pattern candidates.map do |candidate| dup = raw.clone dup[key] = candidate From ade39779c9a0d3238579d48686e7ba38b1751b9a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 5 Apr 2019 20:03:01 -0700 Subject: [PATCH 513/812] Add lsb_release to the Docker image Signed-off-by: Ben Hale --- ci/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/Dockerfile b/ci/Dockerfile index 2fdd1da0f8..cf0d4ebf16 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -6,6 +6,7 @@ RUN apt-get update && apt-get install -y \ git \ libssl-dev \ libreadline-dev \ + lsb-release \ locales \ python \ zip \ From 3978a5d0194df3f05fb4a3767aaeafc920b9142a Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Sat, 6 Apr 2019 07:19:49 -0700 Subject: [PATCH 514/812] Revert "Rubocop required changes" This reverts commit 8ef27921df6f15648d10428d85925cfd3cffe23b. --- lib/java_buildpack/container/dist_zip_like.rb | 4 ++-- lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb | 2 +- lib/java_buildpack/repository/repository_index.rb | 2 +- rakelib/dependency_cache_task.rb | 2 +- rakelib/versions_task.rb | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index ea6bb34cad..60ae1997c5 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -103,9 +103,9 @@ def augment_classpath(content) def augment_classpath_content content = start_script(root).read - if content.match? PATTERN_CLASSPATH + if content =~ PATTERN_CLASSPATH augment_classpath content - elsif content.match? PATTERN_APP_CLASSPATH + elsif content =~ PATTERN_APP_CLASSPATH augment_app_classpath content end end diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index c81ef4265f..70c08f0b17 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -98,7 +98,7 @@ def memory_calculator end def memory_calculator_tar - platform = `uname -s`.match?(/Darwin/) ? 'darwin' : 'linux' + platform = `uname -s` =~ /Darwin/ ? 'darwin' : 'linux' @droplet.sandbox + "bin/java-buildpack-memory-calculator-#{platform}" end diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index a39e19f8aa..e80ba63c3f 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -87,7 +87,7 @@ def platform if redhat_release.exist? tokens = redhat_release.read.match(/(\w+) (?:Linux )?release (\d+)/) "#{tokens[1].downcase}#{tokens[2]}" - elsif `uname -s`.match?(/Darwin/) + elsif `uname -s` =~ /Darwin/ 'mountainlion' elsif !`which lsb_release 2> /dev/null`.empty? `lsb_release -cs`.strip diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index f63a462c1a..7b6f7633b6 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -59,7 +59,7 @@ def initialize def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at raw.map(&block) - elsif raw[:uri].match? pattern + elsif raw[:uri] =~ pattern candidates.map do |candidate| dup = raw.clone dup[key] = candidate diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 7f7535c6a3..eebfc338cd 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -103,7 +103,7 @@ def initialize def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at raw.map(&block) - elsif raw[:uri].match? pattern + elsif raw[:uri] =~ pattern candidates.map do |candidate| dup = raw.clone dup[key] = candidate From 3db1bccda7fb75d1e46cbdee5d7c9b69b439582d Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Sat, 6 Apr 2019 07:25:31 -0700 Subject: [PATCH 515/812] Revert "New minimum Ruby level" This reverts commit 979276525c7fac38a4d6fcf0b2c76d9a25162cd7. --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 7bf4b6a8ae..bc4abe86de 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4.6 +2.3.8 From 58a0e2bf5a2f12916d46182f2513ad2350a5babb Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Sat, 6 Apr 2019 07:34:49 -0700 Subject: [PATCH 516/812] Reinstitute 2.3 on Bionic Signed-off-by: Ben Hale --- .rubocop.yml | 2 ++ ci/Dockerfile | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9e5c9e1794..f197a783bd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -36,6 +36,8 @@ Metrics/PerceivedComplexity: Max: 10 Naming/UncommunicativeMethodParamName: Enabled: false +Performance/RegexpMatch: + Enabled: false RSpec/AnyInstance: Enabled: false RSpec/ExampleLength: diff --git a/ci/Dockerfile b/ci/Dockerfile index cf0d4ebf16..b8243b314b 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -4,7 +4,7 @@ RUN apt-get update && apt-get install -y \ build-essential \ curl \ git \ - libssl-dev \ + libssl1.0-dev \ libreadline-dev \ lsb-release \ locales \ @@ -31,6 +31,9 @@ RUN eval "$(rbenv init -)" \ && git clone https://github.com/sstephenson/rbenv-default-gems.git $(rbenv root)/plugins/rbenv-default-gems \ && echo 'bundler' >> $(rbenv root)/default-gems +RUN eval "$(rbenv init -)" \ + && rbenv install 2.3.8 + RUN eval "$(rbenv init -)" \ && rbenv install 2.4.6 @@ -39,4 +42,3 @@ RUN eval "$(rbenv init -)" \ RUN eval "$(rbenv init -)" \ && rbenv install 2.6.2 - From 542d66c428403191ca3a679a4b7d17541ee86cb6 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 19 Apr 2019 08:58:36 -0700 Subject: [PATCH 517/812] YourKit 2019 Signed-off-by: Ben Hale --- config/your_kit_profiler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml index 287d4f01f4..3a4a77419d 100644 --- a/config/your_kit_profiler.yml +++ b/config/your_kit_profiler.yml @@ -15,7 +15,7 @@ # JMX configuration --- -version: 2018.+ +version: 2019.+ repository_root: https://download.run.pivotal.io/your-kit/{platform}/{architecture} enabled: false port: 10001 From e27b2fa854fc859b13850fc5b413d8f17fbbc9b7 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 9 Jul 2019 16:00:42 -0700 Subject: [PATCH 518/812] New Relic 5.x Signed-off-by: Ben Hale --- config/new_relic_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/new_relic_agent.yml b/config/new_relic_agent.yml index 2820bd00f3..1de53a56b5 100644 --- a/config/new_relic_agent.yml +++ b/config/new_relic_agent.yml @@ -15,7 +15,7 @@ # Configuration for the New Relic framework --- -version: 4.+ +version: 5.+ repository_root: https://download.run.pivotal.io/new-relic extensions: version: 1.+ From 63b6277f714024c03bc6e1699cc2776738a72830 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 15 Jul 2019 10:11:19 -0700 Subject: [PATCH 519/812] Polishing Signed-off-by: Ben Hale --- .idea/inspectionProfiles/profiles_settings.xml | 7 ------- .idea/runConfigurations/All_Tests__2_4_.xml | 2 +- .idea/runConfigurations/All_Tests__2_5_.xml | 2 +- .idea/runConfigurations/All_Tests__2_6_.xml | 2 +- .../runConfigurations/Without_Integration_Tests__2_4_.xml | 2 +- .../runConfigurations/Without_Integration_Tests__2_5_.xml | 2 +- .../runConfigurations/Without_Integration_Tests__2_6_.xml | 2 +- 7 files changed, 6 insertions(+), 13 deletions(-) delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 3b312839bf..0000000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/All_Tests__2_4_.xml b/.idea/runConfigurations/All_Tests__2_4_.xml index dd69d62638..5bb204b942 100644 --- a/.idea/runConfigurations/All_Tests__2_4_.xml +++ b/.idea/runConfigurations/All_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_5_.xml b/.idea/runConfigurations/All_Tests__2_5_.xml index 0b16afa3c6..80804e6bef 100644 --- a/.idea/runConfigurations/All_Tests__2_5_.xml +++ b/.idea/runConfigurations/All_Tests__2_5_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_6_.xml b/.idea/runConfigurations/All_Tests__2_6_.xml index 5fb2fb47f5..9ca5516534 100644 --- a/.idea/runConfigurations/All_Tests__2_6_.xml +++ b/.idea/runConfigurations/All_Tests__2_6_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml index 9bf6e6c3fa..e4c446beb6 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml index 7c6717a82a..0d4b4df2bf 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml index 43a6b4158c..3a184a6142 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml @@ -5,7 +5,7 @@ - + From 473221f9737ffcbe971c0d98bed15c7a3e710b6c Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 15 Jul 2019 10:20:39 -0700 Subject: [PATCH 520/812] Dependency Updates Signed-off-by: Ben Hale --- .rubocop.yml | 2 - Gemfile.lock | 46 +++++++++---------- java-buildpack.iml | 29 ++++++------ .../util/configuration_utils.rb | 4 +- lib/java_buildpack/util/format_duration.rb | 8 ++-- .../util/format_duration_spec.rb | 8 ++-- 6 files changed, 46 insertions(+), 51 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index f197a783bd..9e5c9e1794 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -36,8 +36,6 @@ Metrics/PerceivedComplexity: Max: 10 Naming/UncommunicativeMethodParamName: Enabled: false -Performance/RegexpMatch: - Enabled: false RSpec/AnyInstance: Enabled: false RSpec/ExampleLength: diff --git a/Gemfile.lock b/Gemfile.lock index 0fa6131d0e..21fc46c8ad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,19 +1,18 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.5.2) + addressable (2.6.0) public_suffix (>= 2.0.2, < 4.0) ast (2.4.0) crack (0.4.3) safe_yaml (~> 1.0.0) diff-lcs (1.3) - hashdiff (0.3.8) - jaro_winkler (1.5.2) - parallel (1.12.1) - parser (2.5.3.0) + hashdiff (1.0.0) + jaro_winkler (1.5.3) + parallel (1.17.0) + parser (2.6.3.0) ast (~> 2.4.0) - powerpack (0.1.2) - public_suffix (3.0.3) + public_suffix (3.1.1) rainbow (3.0.0) rake (12.3.2) redcarpet (3.4.0) @@ -21,37 +20,36 @@ GEM rspec-core (~> 3.8.0) rspec-expectations (~> 3.8.0) rspec-mocks (~> 3.8.0) - rspec-core (3.8.0) + rspec-core (3.8.2) rspec-support (~> 3.8.0) - rspec-expectations (3.8.2) + rspec-expectations (3.8.4) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) - rspec-mocks (3.8.0) + rspec-mocks (3.8.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) - rspec-support (3.8.0) - rubocop (0.62.0) + rspec-support (3.8.2) + rubocop (0.72.0) jaro_winkler (~> 1.5.1) parallel (~> 1.10) - parser (>= 2.5, != 2.5.1.1) - powerpack (~> 0.1) + parser (>= 2.6) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 1.4.0) - rubocop-rspec (1.31.0) + unicode-display_width (>= 1.4.0, < 1.7) + rubocop-rspec (1.33.0) rubocop (>= 0.60.0) - ruby-progressbar (1.10.0) - rubyzip (1.2.2) - safe_yaml (1.0.4) + ruby-progressbar (1.10.1) + rubyzip (1.2.3) + safe_yaml (1.0.5) tee (1.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - unicode-display_width (1.4.1) - webmock (3.5.1) + unicode-display_width (1.6.0) + webmock (3.6.0) addressable (>= 2.3.6) crack (>= 0.3.2) - hashdiff - yard (0.9.16) + hashdiff (>= 0.4.0, < 2.0.0) + yard (0.9.20) PLATFORMS ruby @@ -69,4 +67,4 @@ DEPENDENCIES yard BUNDLED WITH - 2.0.1 + 2.0.2 diff --git a/java-buildpack.iml b/java-buildpack.iml index 21cffc3218..6aab3c0607 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -267,33 +267,32 @@ - + - + - - - - - - + + + + + - - - - + + + + - + - + - +
diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 33c13f5ca5..977b32998f 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -120,8 +120,8 @@ def load_configuration(file, user_provided, var_name, clean_nil_values, should_l begin user_provided_value = YAML.safe_load(user_provided) configuration = merge_configuration(configuration, user_provided_value, var_name, should_log) - rescue Psych::SyntaxError => ex - raise "User configuration value in environment variable #{var_name} has invalid syntax: #{ex}" + rescue Psych::SyntaxError => e + raise "User configuration value in environment variable #{var_name} has invalid syntax: #{e}" end logger.debug { "Configuration from #{file} modified with: #{user_provided}" } if should_log end diff --git a/lib/java_buildpack/util/format_duration.rb b/lib/java_buildpack/util/format_duration.rb index a3d90a8d4d..20941eed0f 100644 --- a/lib/java_buildpack/util/format_duration.rb +++ b/lib/java_buildpack/util/format_duration.rb @@ -46,13 +46,13 @@ def duration MILLISECOND = 0.001 - TENTH = (100 * MILLISECOND).freeze + TENTH = 100 * MILLISECOND - SECOND = (10 * TENTH).freeze + SECOND = 10 * TENTH - MINUTE = (60 * SECOND).freeze + MINUTE = 60 * SECOND - HOUR = (60 * MINUTE).freeze + HOUR = 60 * MINUTE private_constant :MILLISECOND, :TENTH, :SECOND, :MINUTE, :HOUR diff --git a/spec/java_buildpack/util/format_duration_spec.rb b/spec/java_buildpack/util/format_duration_spec.rb index 2cc4d884f8..4cc15adebf 100644 --- a/spec/java_buildpack/util/format_duration_spec.rb +++ b/spec/java_buildpack/util/format_duration_spec.rb @@ -47,13 +47,13 @@ MILLISECOND = 0.001 - TENTH = (100 * MILLISECOND).freeze + TENTH = 100 * MILLISECOND - SECOND = (10 * TENTH).freeze + SECOND = 10 * TENTH - MINUTE = (60 * SECOND).freeze + MINUTE = 60 * SECOND - HOUR = (60 * MINUTE).freeze + HOUR = 60 * MINUTE def expect_time_string(expected, time) expect(time.duration).to eq(expected) From cff7e70f971cd20c78177462fbed415cd9f91de8 Mon Sep 17 00:00:00 2001 From: Owen Farrell Date: Thu, 4 Apr 2019 10:58:44 -0400 Subject: [PATCH 521/812] Sanitized whitespace Previously a number of frameworks used the space name of an application directly, extracting it via jq. When those names contained spaces, bad things would happen. This change resolves the problem by adding @sh (a jq directive) to each extraction ensuring an escaped version of each value. [resolves #712][resolves #713] Signed-off-by: Ben Hale --- config/app_dynamics_agent.yml | 4 ++-- config/contrast_security_agent.yml | 2 +- config/sky_walking_agent.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 258cc3c217..71083e137e 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -17,6 +17,6 @@ --- version: 4.+ repository_root: https://packages.appdynamics.com/java -default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name") -default_node_name: $(jq -r -n "$VCAP_APPLICATION | .application_name + \":$CF_INSTANCE_INDEX\"") +default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") +default_node_name: $(jq -r -n "$VCAP_APPLICATION | .application_name"):$CF_INSTANCE_INDEX default_tier_name: diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index d6fdfd9f8d..45ee5972a4 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -16,5 +16,5 @@ # Configuration for the ContrastSecurity framework --- version: 3.+ -default_server_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name + \":$CF_INSTANCE_INDEX\"") +default_server_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh"):$CF_INSTANCE_INDEX repository_root: https://artifacts.contrastsecurity.com/agents/java diff --git a/config/sky_walking_agent.yml b/config/sky_walking_agent.yml index ce6cb013f9..0b9c3d3b8c 100644 --- a/config/sky_walking_agent.yml +++ b/config/sky_walking_agent.yml @@ -17,4 +17,4 @@ --- version: 3.+ repository_root: https://java-buildpack.cloudfoundry.org/sky-walking -default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name") +default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") From 3f95b097fd50c794b58d29bdd9882b21772740c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Bl=C3=A4si?= Date: Thu, 21 Mar 2019 14:07:14 +0100 Subject: [PATCH 522/812] Jacoco Output Mode Previously, the only supported output mode was tcpclient. This change allows configuration of that value. [resolves #715] Signed-off-by: Ben Hale --- docs/framework-jacoco_agent.md | 5 +++-- lib/java_buildpack/framework/jacoco_agent.rb | 1 + spec/java_buildpack/framework/jacoco_agent_spec.rb | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/framework-jacoco_agent.md b/docs/framework-jacoco_agent.md index d493082d82..c97d75e08a 100644 --- a/docs/framework-jacoco_agent.md +++ b/docs/framework-jacoco_agent.md @@ -23,10 +23,11 @@ The credential payload of the service may contain the following entries: | Name | Description | ---- | ----------- -| `address` | The host for the agent to connect to +| `address` | The host for the agent to connect to or listen on | `excludes` | (Optional) A list of class names that should be excluded from execution analysis. The list entries are separated by a colon (:) and may use wildcard characters (* and ?). | `includes` | (Optional) A list of class names that should be included in execution analysis. The list entries are separated by a colon (:) and may use wildcard characters (* and ?). -| `port` | (Optional) The port for the agent to connect to +| `port` | (Optional) The port for the agent to connect to or listen on +| `output` | (Optional) The mode for the agent. Possible values are either tcpclient (default) or tcpserver. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/jacoco_agent.rb b/lib/java_buildpack/framework/jacoco_agent.rb index 9a33f13d27..bf4455cfeb 100644 --- a/lib/java_buildpack/framework/jacoco_agent.rb +++ b/lib/java_buildpack/framework/jacoco_agent.rb @@ -41,6 +41,7 @@ def release properties['excludes'] = credentials['excludes'] if credentials.key? 'excludes' properties['includes'] = credentials['includes'] if credentials.key? 'includes' properties['port'] = credentials['port'] if credentials.key? 'port' + properties['output'] = credentials['output'] if credentials.key? 'output' @droplet.java_opts.add_javaagent_with_props(@droplet.sandbox + 'jacocoagent.jar', properties) end diff --git a/spec/java_buildpack/framework/jacoco_agent_spec.rb b/spec/java_buildpack/framework/jacoco_agent_spec.rb index 7481969ce3..ab72167edf 100644 --- a/spec/java_buildpack/framework/jacoco_agent_spec.rb +++ b/spec/java_buildpack/framework/jacoco_agent_spec.rb @@ -56,6 +56,7 @@ it 'updates JAVA_OPTS with additional options' do allow(services).to receive(:find_service).and_return('credentials' => { 'address' => 'test-address', + 'output' => 'test-output', 'excludes' => 'test-excludes', 'includes' => 'test-includes', 'port' => 6300 }) @@ -63,7 +64,7 @@ component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/jacoco_agent/jacocoagent.jar=' \ - 'address=test-address,output=tcpclient,sessionid=$CF_INSTANCE_GUID,' \ + 'address=test-address,output=test-output,sessionid=$CF_INSTANCE_GUID,' \ 'excludes=test-excludes,includes=test-includes,port=6300') end From eebfdce1fdacb51063218d0fa4cd6dffb26f3e64 Mon Sep 17 00:00:00 2001 From: dmevada Date: Mon, 8 Apr 2019 15:22:44 -0700 Subject: [PATCH 523/812] Generic Introscope Properties Previously in order to handle Introscope properties, a new value would have to be added to the framework for integration. This made arbitrary configuration difficult and brittle. This change updates the framework to behave like many of the others and do a generic mapping from any unknown credential payload property to a system property with a fixed prefix. [resolves $717] Signed-off-by: Ben Hale --- docs/framework-introscope_agent.md | 17 +++++++------ .../framework/introscope_agent.rb | 25 +++++++++++++------ .../framework/introscope_agent_spec.rb | 20 +++++++++------ 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/docs/framework-introscope_agent.md b/docs/framework-introscope_agent.md index 5e92103e78..106d706dd6 100644 --- a/docs/framework-introscope_agent.md +++ b/docs/framework-introscope_agent.md @@ -19,16 +19,19 @@ Tags are printed to standard output by the buildpack detect script ## User-Provided Service (Optional) Users may optionally provide their own Introscope service. A user-provided Introscope service must have a name or tag with `introscope` in it so that the Introscope Agent Framework will automatically configure the application to work with the service. -The credential payload of the service may contain the following entries: +The credential payload of the service may contain any valid CA APM Java agent property. + +The table below displays a subset of properties that are accepted by the buildpack. +Please refer to CA APM docs for a full list of valid agent properties. + | Name | Description | ---- | ----------- -|`agent_default_process_name`| (Optional) The name that is specified for the agent process. If not specified, default value is the application name. -| `agent_manager_credential` | (Optional) The credential that is used to connect to the Enterprise Manager server -| `agent_manager_url` | The url of the Enterprise Manager server -| `agent_name` | (Optional) The name that should be given to this instance of the Introscope agent -| `credential`| (Deprecated) The credential that is used to connect to the Enterprise Manager server -| `url` | (Deprecated) The url of the Enterprise Manager server +|`agent_manager_credential`| (Optional) The credential that is used to connect to the Enterprise Manager server. +|`agentManager_url_1` | The url of the Enterprise Manager server. +|`agent_manager_url`| (Deprecated) The url of the Enterprise Manager server. +|`credential`| (Deprecated) The credential that is used to connect to the Enterprise Manager server + To provide more complex values such as the `agent_name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `agent_name` could be set with a value of `agent-$(expr "$VCAP_APPLICATION" : '.*application_name[": ]*\([[:word:]]*\).*')` to calculate a value from the Cloud Foundry application name. diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index 0d22b87cfb..75abbc32f5 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -34,7 +34,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, %w[agent_manager_url url])['credentials'] + credentials = @application.services.find_service(FILTER)['credentials'] java_opts = @droplet.java_opts java_opts @@ -44,18 +44,14 @@ def release .add_system_property('com.wily.introscope.agent.agentName', agent_name(credentials)) .add_system_property('introscope.agent.defaultProcessName', default_process_name(credentials)) - if agent_manager_credential(credentials) - java_opts.add_system_property('agentManager.credential', agent_manager_credential(credentials)) - end - - add_url(credentials, java_opts) + export_all_properties(credentials, java_opts) end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, %w[agent_manager_url url] + @application.services.one_service? FILTER, %w[agentManager_url_1 agent_manager_url] end private @@ -121,12 +117,25 @@ def protocol_mapping(protocol) end def agent_manager_url(credentials) - credentials['agent_manager_url'] || credentials['url'] + credentials['agentManager_url_1'] || credentials['agent_manager_url'] end def agent_manager_credential(credentials) credentials['agent_manager_credential'] || credentials['credential'] end + + def export_all_properties(credentials, java_opts) + credentials.keys.each do |key| + correct_key = key.tr('_', '.') + if %w[agentManager.url.1 agent.manager.url].include?(correct_key) + add_url(credentials, java_opts) + elsif %w[agent.manager.credential credential].include?(correct_key) + java_opts.add_system_property('agentManager.credential', agent_manager_credential(credentials)) + else + java_opts.add_system_property(correct_key, credentials[key]) + end + end + end end end end diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index b1d498e7c5..c0f46b1562 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -40,7 +40,8 @@ let(:credentials) { {} } before do - allow(services).to receive(:one_service?).with(/introscope/, %w[agent_manager_url url]).and_return(true) + allow(services).to receive(:one_service?).with(/introscope/, + %w[agentManager_url_1 agent_manager_url]).and_return(true) allow(services).to receive(:find_service).and_return('credentials' => credentials) end @@ -56,7 +57,7 @@ end context do - let(:credentials) { { 'agent_name' => 'another-test-agent-name', 'url' => 'default-host:5001' } } + let(:credentials) { { 'agent_name' => 'another-test-agent-name', 'agent_manager_url' => 'default-host:5001' } } it 'adds agent_name from credentials to JAVA_OPTS if specified' do component.release @@ -67,7 +68,7 @@ context do - let(:credentials) { { 'url' => 'test-host-name:5001' } } + let(:credentials) { { 'agent_manager_url' => 'test-host-name:5001' } } it 'parses the url and sets host port and default socket factory' do component.release @@ -114,7 +115,7 @@ end context do - let(:credentials) { { 'url' => 'ssl://test-host-name:5443' } } + let(:credentials) { { 'agent_manager_url' => 'ssl://test-host-name:5443' } } it 'parses the url and sets host, port, and ssl socket factory' do component.release @@ -160,7 +161,7 @@ end context do - let(:credentials) { { 'url' => 'http://test-host-name:8081' } } + let(:credentials) { { 'agent_manager_url' => 'http://test-host-name:8081' } } it 'parses the url and sets host, port, and http socket factory' do component.release @@ -206,7 +207,7 @@ end context do - let(:credentials) { { 'url' => 'https://test-host-name:8444' } } + let(:credentials) { { 'agent_manager_url' => 'https://test-host-name:8444' } } it 'parses the url and sets host, port, and https socket factory' do component.release @@ -252,7 +253,10 @@ end context do - let(:credentials) { { 'url' => 'https://test-host-name:8444', 'credential' => 'test-credential-cccf-88-ae' } } + let(:credentials) do + { 'agent_manager_url' => 'https://test-host-name:8444', + 'agent_manager_credential' => 'test-credential-cccf-88-ae' } + end it 'sets the url and also the credential' do component.release @@ -304,7 +308,7 @@ context do let(:credentials) do - { 'agent_manager_url' => 'https://test-host-name:8444', + { 'agentManager_url_1' => 'https://test-host-name:8444', 'agent_manager_credential' => 'test-credential-cccf-88-ae', 'agent_default_process_name' => 'TestProcess' } end From 00cd07f2c3d0dcb059936f52fca7fb9bf1f2a48c Mon Sep 17 00:00:00 2001 From: Markus Strehle Date: Tue, 7 May 2019 09:26:45 +0200 Subject: [PATCH 524/812] Hide Tomcat Internals Previously, when Tomcat returned an error it would print a bunch of information including a report and information about the Tomcat server that was running. This change hardens the Tomcat configuration to hide that information by default. [resolves #724] Signed-off-by: Ben Hale --- resources/tomcat/conf/server.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/tomcat/conf/server.xml b/resources/tomcat/conf/server.xml index e4496a9669..bf21567c87 100644 --- a/resources/tomcat/conf/server.xml +++ b/resources/tomcat/conf/server.xml @@ -28,6 +28,7 @@ + From cf7dcb70e256d06a62d7bb25ec4331696f22c699 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 15 Jul 2019 10:52:47 -0700 Subject: [PATCH 525/812] Integration Dependency Version Updates Signed-off-by: Ben Hale --- config/groovy.yml | 2 +- config/jprofiler_profiler.yml | 2 +- config/postgresql_jdbc.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/groovy.yml b/config/groovy.yml index d90959104d..649c9d3a78 100644 --- a/config/groovy.yml +++ b/config/groovy.yml @@ -15,5 +15,5 @@ # Configuration for the Groovy container --- -version: 2.4.+ +version: 2.5.+ repository_root: "{default.repository.root}/groovy" diff --git a/config/jprofiler_profiler.yml b/config/jprofiler_profiler.yml index 7de594ddb7..1fed02e236 100644 --- a/config/jprofiler_profiler.yml +++ b/config/jprofiler_profiler.yml @@ -15,7 +15,7 @@ # JMX configuration --- -version: 10.+ +version: 11.+ repository_root: https://download.run.pivotal.io/jprofiler enabled: false nowait: true diff --git a/config/postgresql_jdbc.yml b/config/postgresql_jdbc.yml index bf153e71dd..885af2a046 100644 --- a/config/postgresql_jdbc.yml +++ b/config/postgresql_jdbc.yml @@ -15,5 +15,5 @@ # Configuration for the Postgresql JDBC framework --- -version: 9.4.+ +version: 42.+ repository_root: "{default.repository.root}/postgresql-jdbc" From a8cb63dd6316b151f94781821540eb338c2b217b Mon Sep 17 00:00:00 2001 From: Seymur Farziyev Date: Wed, 5 Jun 2019 13:49:16 +0200 Subject: [PATCH 526/812] Dynatrace Location Variables This change updates the name of the Dynatrace location variables to match correct expectations. [resolves #729] Signed-off-by: Ben Hale --- .../framework/dynatrace_one_agent.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 82043fdffa..1cce938d93 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -93,18 +93,18 @@ def supports? DT_LOGSTREAM = 'DT_LOGSTREAM' - DT_LOCATION = 'DT_LOCATION' + DT_NETWORK_ZONE = 'DT_NETWORK_ZONE' ENVIRONMENTID = 'environmentid' FILTER = /dynatrace/.freeze - LOCATION = 'location' + NETWORKZONE = 'networkzone' SKIP_ERRORS = 'skiperrors' - private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_LOCATION, :DT_LOGSTREAM, - :DT_TENANT, :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :LOCATION, :SKIP_ERRORS + private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_NETWORK_ZONE, :DT_LOGSTREAM, + :DT_TENANT, :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :NETWORKZONE, :SKIP_ERRORS def agent_download_url download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ @@ -148,7 +148,7 @@ def dynatrace_environment_variables(manifest) .add_environment_variable(DT_CONNECTION_POINT, endpoints(manifest)) environment_variables.add_environment_variable(DT_APPLICATION_ID, application_id) unless application_id? - environment_variables.add_environment_variable(DT_LOCATION, credentials[LOCATION]) if location? + environment_variables.add_environment_variable(DT_NETWORK_ZONE, credentials[NETWORKZONE]) if networkzone? environment_variables.add_environment_variable(DT_LOGSTREAM, 'stdout') unless logstream? end @@ -170,8 +170,8 @@ def expand(file) end end - def location? - credentials.key?(LOCATION) + def networkzone? + credentials.key?(NETWORKZONE) end def logstream? From 6225e2ce2c661b57787335361b03986804601d8c Mon Sep 17 00:00:00 2001 From: Blaine Forbush Date: Wed, 5 Jun 2019 10:02:28 -0600 Subject: [PATCH 527/812] Bionic URL Previously, the OpenJDK documentation didn't include a link to bionic versions. This change updates the docs to include it. [resolves #730] Signed-off-by: Ben Hale --- docs/jre-open_jdk_jre.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index c2c7dd368c..0115bc8dc6 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -25,7 +25,7 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | Name | Description | ---- | ----------- | `jre.repository_root` | The URL of the OpenJDK repository index ([details][repositories]). -| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [mountainlion][] and [trusty][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [mountainlion][], [trusty][] and [bionic][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). | `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [mountainlion][jvmkill-mountainlion] and [trusty][jvmkill-trusty]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". @@ -163,3 +163,4 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [trusty]: http://download.pivotal.io.s3.amazonaws.com/openjdk/trusty/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering [Volume Service]: https://docs.cloudfoundry.org/devguide/services/using-vol-services.html +[bionic]: http://download.pivotal.io.s3.amazonaws.com/openjdk/bionic/x86_64/index.yml From 77818c18efab4dd434eaa1b052cc4658188a0909 Mon Sep 17 00:00:00 2001 From: fwang Date: Tue, 25 Jun 2019 16:46:54 -0400 Subject: [PATCH 528/812] Riverbed Always Connects to Service Broker Previously when the Riverbed integration was trying to download an agent from the service broker, it could be stopped by an offline buildpack. Given that download from the service broker should always work (offline is relative to the internet, not the internal network), this change enables the framework to download from the service broker no matter what. [resolves #734] Signed-off-by: Ben Hale --- .../framework/riverbed_appinternals_agent.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb index b56c4455fc..4167c440a6 100644 --- a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb +++ b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb @@ -34,8 +34,14 @@ def initialize(context) # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_zip(false, @droplet.sandbox, @component_name) + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, 'Downloading from Riverbed AppInternals Service Broker' + ) do + download_zip(false, @droplet.sandbox, @component_name) + end @droplet.copy_resources + rescue StandardError => e + raise "Riverbed AppInternals download failed: #{e}" end # (see JavaBuildpack::Component::BaseComponent#release) From 1e9deff9aefac9b65c333b2993f2d4abcc59b845 Mon Sep 17 00:00:00 2001 From: Pavan Krishna Date: Wed, 10 Jul 2019 13:08:15 -0700 Subject: [PATCH 529/812] Access Key Secret and Unique HostID This change adds two new pieces of functionality. First, parsing of the services payload now looks for an access-key-secret payload for authenticating. Second, the configuration now has a default (or dynamically configured) UNIQUE_HOST_ID. [resolves #738] Signed-off-by: Ben Hale --- config/app_dynamics_agent.yml | 3 ++- lib/java_buildpack/framework/app_dynamics_agent.rb | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 71083e137e..00abe7fbef 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -18,5 +18,6 @@ version: 4.+ repository_root: https://packages.appdynamics.com/java default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") -default_node_name: $(jq -r -n "$VCAP_APPLICATION | .application_name"):$CF_INSTANCE_INDEX +default_node_name: $(jq -r -n "$VCAP_APPLICATION | .application_name + \":$CF_INSTANCE_INDEX\"") default_tier_name: +default_unique_host_name: $(jq -r -n "$VCAP_APPLICATION | .application_id + \":$CF_INSTANCE_INDEX\"") diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 78b4e43ac6..b681f8d3b6 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -52,6 +52,7 @@ def release host_name java_opts, credentials port java_opts, credentials ssl_enabled java_opts, credentials + unique_host_name java_opts end protected @@ -74,7 +75,7 @@ def application_name(java_opts, credentials) end def account_access_key(java_opts, credentials) - account_access_key = credentials['account-access-key'] + account_access_key = credentials['account-access-key'] || credentials.dig('account-access-secret', 'secret') java_opts.add_system_property 'appdynamics.agent.accountAccessKey', account_access_key if account_access_key end @@ -111,6 +112,11 @@ def tier_name(java_opts, credentials) java_opts.add_system_property('appdynamics.agent.tierName', name.to_s) end + def unique_host_name(java_opts) + name = @configuration['default_unique_host_name'] || @application.details['application_name'] + java_opts.add_system_property('appdynamics.agent.uniqueHostId', name.to_s) + end + # Copy default configuration present in resources folder of app_dynamics_agent ver* directories present in sandbox # # @param [Pathname] default_conf_dir the 'defaults' directory present in app_dynamics_agent resources. From be0d204581105b4e196b9ef3e649d23b52699c8b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 15 Jul 2019 11:48:38 -0700 Subject: [PATCH 530/812] Modern SkyWalking Agent This change makes the updates required to use SkyWalking 6.x and later. [resolves #714] Signed-off-by: Ben Hale --- config/sky_walking_agent.yml | 2 +- .../framework/sky_walking_agent.rb | 2 +- spec/fixtures/stub-skywalking-agent.tar.gz | Bin 169 -> 191 bytes .../framework/sky_walking_agent_spec.rb | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/sky_walking_agent.yml b/config/sky_walking_agent.yml index 0b9c3d3b8c..1ac44a211c 100644 --- a/config/sky_walking_agent.yml +++ b/config/sky_walking_agent.yml @@ -15,6 +15,6 @@ # Configuration for the Sky Walking framework. --- -version: 3.+ +version: 6.+ repository_root: https://java-buildpack.cloudfoundry.org/sky-walking default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") diff --git a/lib/java_buildpack/framework/sky_walking_agent.rb b/lib/java_buildpack/framework/sky_walking_agent.rb index 8daa5de585..527a61fcb6 100644 --- a/lib/java_buildpack/framework/sky_walking_agent.rb +++ b/lib/java_buildpack/framework/sky_walking_agent.rb @@ -35,7 +35,7 @@ def compile def release credentials = @application.services.find_service(FILTER, 'servers')['credentials'] java_opts = @droplet.java_opts - java_opts.add_javaagent(@droplet.sandbox + 'skywalking-agent.jar') + java_opts.add_javaagent(@droplet.sandbox + 'agent/skywalking-agent.jar') application_name java_opts, credentials sample_n_per_3_secs java_opts, credentials diff --git a/spec/fixtures/stub-skywalking-agent.tar.gz b/spec/fixtures/stub-skywalking-agent.tar.gz index f0a11abe9861ab27c98a2d39b90aa473ea225105..d45c0894460775024b35c1c3a373f9a7cf15076e 100644 GIT binary patch literal 191 zcmb2|=3tn7R40~!`R!##z9s{K*2KO`+$(Zt9;(b@S|K3TWO(nMTL(9f1n&%i|M|wA zw~zY7-=4C4_4-rEu{kvpufElrHUFAbsh@4urO@1^t8G)0(vy_KdO~k?Og0J1YmAGF znRRWxv-a=i^_x12A4bgcfAhWA=Czl};XmRPtn;707b<-6pIiAS|Mcz43q0?0eV^E| p=k)!q?$TA4C+s)vHVlDubcuYmZBgq|G=`_4b} zz7=`KKm7i>g)94Ww{nJF{I)x#QfboaS?<3SkM2@*S3A4rvQN>;wG*$b{B`67e^q7S z%U=b3Yv1rM)J%Jo6d8H$Pk*sZvFfguf0y&$4vslr{>W}mvHYF;UAIgOH=St7|MT-N TBLfmxb6xgI@_Rc54F(1PC8|&< diff --git a/spec/java_buildpack/framework/sky_walking_agent_spec.rb b/spec/java_buildpack/framework/sky_walking_agent_spec.rb index 3c4b2e53a4..023aa7c7bb 100644 --- a/spec/java_buildpack/framework/sky_walking_agent_spec.rb +++ b/spec/java_buildpack/framework/sky_walking_agent_spec.rb @@ -48,7 +48,7 @@ component.compile - expect(sandbox + 'skywalking-agent.jar').to exist + expect(sandbox + 'agent/skywalking-agent.jar').to exist end it 'raises error if servers not specified' do @@ -62,7 +62,7 @@ it 'updates JAVA_OPTS' do component.release - expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/sky_walking_agent/skywalking-agent.jar') + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/sky_walking_agent/agent/skywalking-agent.jar') expect(java_opts).to include('-Dskywalking.collector.servers=test-servers') expect(java_opts).to include('-Dskywalking.agent.application_code=test-application-name') end From abc7b510246fc2d710da365819049f444043d224 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 17 Jul 2019 14:03:24 -0700 Subject: [PATCH 531/812] Switch to HTTPS Signed-off-by: Ben Hale --- config/luna_security_provider.yml | 2 +- config/oracle_jre.yml | 2 +- config/protect_app_security_provider.yml | 2 +- config/zulu_jre.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index ec8235c18c..14074dcf0c 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -16,7 +16,7 @@ # Configuration for the Luna Security Provider framework --- version: 6.+ -repository_root: http://files.cf-hsm.io/luna-installer +repository_root: https://files.cf-hsm.io/luna-installer ha_logging_enabled: true logging_enabled: false tcp_keep_alive_enabled: false diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index 2ec915286e..dd383e409a 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -17,7 +17,7 @@ # Pre Java 1.8, permgen was used instead of metaspace. Please see the documentation for more detail. # You must specify a the repository root of an Oracle JRE repository. Please see the documentation for more detail. -# e.g. repository_root: "http://example.com/oracle-jre/{platform}/{architecture}" +# e.g. repository_root: "https://example.com/oracle-jre/{platform}/{architecture}" --- jre: version: 1.8.0_+ diff --git a/config/protect_app_security_provider.yml b/config/protect_app_security_provider.yml index 1a4246313d..ac62b1f7f0 100644 --- a/config/protect_app_security_provider.yml +++ b/config/protect_app_security_provider.yml @@ -16,4 +16,4 @@ # Configuration for the ProtectApp Security Provider framework --- version: 8.4.+ -repository_root: http://files.cf-hsm.io/protectapp-installer +repository_root: https://files.cf-hsm.io/protectapp-installer diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 9e3d9d7c9a..91742dca29 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -17,7 +17,7 @@ # Pre Java 1.8, permgen was used instead of metaspace. Please see the documentation for more detail. # You must specify a the repository root of an Zulu JRE repository. Please see the documentation for more detail. -# e.g. repository_root: "http://example.com/zulu-jre/{platform}/{architecture}" +# e.g. repository_root: "https://example.com/zulu-jre/{platform}/{architecture}" --- jre: version: 1.8.0_+ From a7f28d670fab254530d5c498b62900158b45979d Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 23 Jul 2019 12:02:41 -0600 Subject: [PATCH 532/812] Update Gemalto Version Numbers Signed-off-by: Ben Hale --- config/luna_security_provider.yml | 2 +- config/protect_app_security_provider.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index 14074dcf0c..ae3e7806de 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -15,7 +15,7 @@ # Configuration for the Luna Security Provider framework --- -version: 6.+ +version: 7.+ repository_root: https://files.cf-hsm.io/luna-installer ha_logging_enabled: true logging_enabled: false diff --git a/config/protect_app_security_provider.yml b/config/protect_app_security_provider.yml index ac62b1f7f0..4f4b0b79e5 100644 --- a/config/protect_app_security_provider.yml +++ b/config/protect_app_security_provider.yml @@ -15,5 +15,5 @@ # Configuration for the ProtectApp Security Provider framework --- -version: 8.4.+ +version: 8.+ repository_root: https://files.cf-hsm.io/protectapp-installer From bfe3412d5a4da8a36ea3e741540c1694596ae021 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 25 Jul 2019 08:27:43 -0700 Subject: [PATCH 533/812] OverOps HTTPS download Signed-off-by: Ben Hale --- config/takipi_agent.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/takipi_agent.yml b/config/takipi_agent.yml index eb7adfb3dd..6ae76b323d 100644 --- a/config/takipi_agent.yml +++ b/config/takipi_agent.yml @@ -16,6 +16,6 @@ # Configuration for the Takipi framework --- version: 4.+ -repository_root: http://get.takipi.com/cloudfoundry +repository_root: https://get.takipi.com/cloudfoundry node_name_prefix: node -application_name: +application_name: From 6fa8eee3d04d01b26d1c0924e307f865263c7e32 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 21 Aug 2019 11:06:05 -0700 Subject: [PATCH 534/812] Micrometer Tags This change updates the Metric Writer to remove integration with the now EOL'd Metrics Forwarder and instead add a set of Cloud Foundry-specific tags to Micrometer metrics. [resolves #644] Signed-off-by: Ben Hale --- .idea/codeStyles/Project.xml | 1 - config/metric_writer.yml | 3 +- docs/framework-metric_writer.md | 28 ++++---- java-buildpack.iml | 10 +-- lib/java_buildpack/framework/metric_writer.rb | 19 +----- .../framework/spring_auto_reconfiguration.rb | 9 --- spec/droplet_helper.rb | 1 + .../micrometer-core-1.1.5.jar | 0 .../framework/metric_writer_spec.rb | 66 +++++++------------ 9 files changed, 50 insertions(+), 87 deletions(-) create mode 100644 spec/fixtures/framework_metric_writer/micrometer-core-1.1.5.jar diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 2afc9d8a0d..c688e58fe5 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -6,7 +6,6 @@
diff --git a/lib/java_buildpack/framework/metric_writer.rb b/lib/java_buildpack/framework/metric_writer.rb index 08cfc68c42..6dd251ac74 100644 --- a/lib/java_buildpack/framework/metric_writer.rb +++ b/lib/java_buildpack/framework/metric_writer.rb @@ -32,32 +32,15 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, ACCESS_KEY, ENDPOINT)['credentials'] - @droplet.additional_libraries << (@droplet.sandbox + jar_name) - @droplet.java_opts - .add_system_property('cloudfoundry.metrics.accessToken', credentials[ACCESS_KEY]) - .add_system_property('cloudfoundry.metrics.applicationId', @application.details['application_id']) - .add_system_property('cloudfoundry.metrics.endpoint', credentials[ENDPOINT]) - .add_system_property('cloudfoundry.metrics.instanceId', '$CF_INSTANCE_GUID') - .add_system_property('cloudfoundry.metrics.instanceIndex', '$CF_INSTANCE_INDEX') end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, ACCESS_KEY, ENDPOINT + @configuration['enabled'] && (@droplet.root + '**/*micrometer-core*.jar').glob.any? end - - ACCESS_KEY = 'access_key' - - ENDPOINT = 'endpoint' - - FILTER = /metrics-forwarder/.freeze - - private_constant :ACCESS_KEY, :ENDPOINT, :FILTER - end end diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 5e5db78ecf..00e9651f09 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -16,7 +16,6 @@ # limitations under the License. require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/logging/logger_factory' require 'java_buildpack/framework' module JavaBuildpack @@ -26,14 +25,6 @@ module Framework # applications. class SpringAutoReconfiguration < JavaBuildpack::Component::VersionedDependencyComponent - # Creates an instance - # - # @param [Hash] context a collection of utilities used the component - def initialize(context) - super(context) - @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger SpringAutoReconfiguration - end - # (see JavaBuildpack::Component::BaseComponent#compile) def compile download_jar diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index 9ce0387da6..8e648c723f 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -26,6 +26,7 @@ require 'java_buildpack/component/java_opts' require 'java_buildpack/component/mutable_java_home' require 'java_buildpack/component/networking' +require 'java_buildpack/component/root_libraries' require 'java_buildpack/component/security_providers' require 'java_buildpack/util/snake_case' require 'java_buildpack/util/tokenized_version' diff --git a/spec/fixtures/framework_metric_writer/micrometer-core-1.1.5.jar b/spec/fixtures/framework_metric_writer/micrometer-core-1.1.5.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/metric_writer_spec.rb b/spec/java_buildpack/framework/metric_writer_spec.rb index 2385343c57..4297de93c3 100644 --- a/spec/java_buildpack/framework/metric_writer_spec.rb +++ b/spec/java_buildpack/framework/metric_writer_spec.rb @@ -22,60 +22,44 @@ describe JavaBuildpack::Framework::MetricWriter do include_context 'with component help' - it 'does not detect without metric-forwarder service' do - expect(component.detect).to be_nil - end - - context do - - before do - allow(services).to receive(:one_service?).with(/metrics-forwarder/, 'access_key', 'endpoint').and_return(true) - end - - it 'detects with metric-forwarder service' do - expect(component.detect).to eq("metric-writer=#{version}") - end + let(:configuration) { { 'enabled' => true } } - it 'downloads Metric Writer JAR', - cache_fixture: 'stub-metric-writer.jar' do + it 'detects with Micrometer JAR', + app_fixture: 'framework_metric_writer' do - component.compile + expect(component.detect).to eq("metric-writer=#{version}") + end - expect(sandbox + "metric_writer-#{version}.jar").to exist - end + it 'does not detect without Micrometer JAR' do + expect(component.detect).to be_nil + end - it 'adds the metric writer to the additional libraries in compile when needed', - cache_fixture: 'stub-metric-writer.jar' do + context do + let(:configuration) { { 'enabled' => false } } - component.compile + it 'does not detect if disabled', + app_fixture: 'framework_metric_writer' do - expect(additional_libraries).to include(sandbox + "metric_writer-#{version}.jar") + expect(component.detect).to be_nil end + end - it 'adds the metric writer to the additional libraries in release when needed', - cache_fixture: 'stub-metric-writer.jar' do - - allow(services).to receive(:find_service).and_return('credentials' => { 'access_key' => 'test-access-key', - 'endpoint' => 'https://test-endpoint' }) - - component.release + it 'downloads additional libraries', + app_fixture: 'framework_metric_writer', + cache_fixture: 'stub-metric-writer.jar' do - expect(additional_libraries).to include(sandbox + "metric_writer-#{version}.jar") - end + component.compile - it 'updates JAVA_OPTS' do - allow(services).to receive(:find_service).and_return('credentials' => { 'access_key' => 'test-access-key', - 'endpoint' => 'https://test-endpoint' }) + expect(sandbox + "metric_writer-#{version}.jar").to exist + end - component.release + it 'adds to additional libraries', + app_fixture: 'framework_metric_writer', + cache_fixture: 'stub-metric-writer.jar' do - expect(java_opts).to include('-Dcloudfoundry.metrics.accessToken=test-access-key') - expect(java_opts).to include('-Dcloudfoundry.metrics.applicationId=test-application-id') - expect(java_opts).to include('-Dcloudfoundry.metrics.endpoint=https://test-endpoint') - expect(java_opts).to include('-Dcloudfoundry.metrics.instanceId=$CF_INSTANCE_GUID') - expect(java_opts).to include('-Dcloudfoundry.metrics.instanceIndex=$CF_INSTANCE_INDEX') - end + component.release + expect(additional_libraries).to include(sandbox + "metric_writer-#{version}.jar") end end From 97e22eca2ae948e62a43512c264a07332b0851d5 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 4 Sep 2019 08:49:42 -0700 Subject: [PATCH 535/812] Bundler Exclusion Signed-off-by: Ben Hale --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c3b086ec31..ad9e5451be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.bundle/ .idea/.rakeTasks .idea/tasks.xml .idea/workspace.xml From bee70cd1cdf0b5b900d1e17cffea1858dee8d9ed Mon Sep 17 00:00:00 2001 From: dmevada Date: Fri, 26 Jul 2019 09:28:54 -0700 Subject: [PATCH 536/812] Introscope Agent Upgrade This change upgrades the version wildcard for Introscope to choose 11.x line of releases. [resolves #739] Signed-off-by: Ben Hale --- config/introscope_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index 30380c586e..6740730d70 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -15,6 +15,6 @@ # Configuration for the CA Wily framework --- -version: 10.+ +version: 11.+ repository_root: https://ca.bintray.com/apm-agents default_agent_name: $(jq -r -n "$VCAP_APPLICATION | .application_name") From f3f340817133b2719b8e80398f880908ed390182 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 4 Sep 2019 09:23:20 -0700 Subject: [PATCH 537/812] Polishing Signed-off-by: Ben Hale --- config/takipi_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/takipi_agent.yml b/config/takipi_agent.yml index 6ae76b323d..cda0be6cfb 100644 --- a/config/takipi_agent.yml +++ b/config/takipi_agent.yml @@ -18,4 +18,4 @@ version: 4.+ repository_root: https://get.takipi.com/cloudfoundry node_name_prefix: node -application_name: +application_name: From 0bc7378ff011fd60fc016f8e7428742d8d8d9825 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 4 Sep 2019 09:25:06 -0700 Subject: [PATCH 538/812] Polishing Signed-off-by: Ben Hale --- docs/framework-metric_writer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/framework-metric_writer.md b/docs/framework-metric_writer.md index 8436317c26..aeaaff0a5a 100644 --- a/docs/framework-metric_writer.md +++ b/docs/framework-metric_writer.md @@ -8,7 +8,7 @@ The Metric Writer Framework causes an application to be automatically configured Tags - spring-auto-reconfiguration=<version> + metric-writer-reconfiguration=<version> Tags are printed to standard output by the buildpack detect script @@ -33,7 +33,7 @@ The framework can be configured by modifying the [`config/metric_writer.yml`][] | Name | Description | ---- | ----------- -| `enabled` | Whether to attempt auto-reconfiguration +| `enabled` | Whether to attempt metric augmentation | `repository_root` | The URL of the Metric Writer repository index ([details][repositories]). | `version` | The version of Metric Writer to use. Candidate versions can be found in [this listing][]. From c98dd6b6599057e7861f94fa91bc97beb68edf89 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 9 Sep 2019 11:43:19 -0700 Subject: [PATCH 539/812] Remove Trusty Support Signed-off-by: Ben Hale --- docs/extending-repositories.md | 6 +++--- docs/framework-google_stackdriver_debugger.md | 2 +- docs/framework-google_stackdriver_profiler.md | 2 +- docs/framework-your_kit_profiler.md | 6 ++---- docs/jre-open_jdk_jre.md | 11 ++++------- docs/jre-oracle_jre.md | 5 ++--- docs/jre-sap_machine_jre.md | 12 +++++------- docs/jre-zulu_jre.md | 5 ++--- rakelib/package.rb | 2 +- 9 files changed, 21 insertions(+), 30 deletions(-) diff --git a/docs/extending-repositories.md b/docs/extending-repositories.md index d30ecef12c..f1c58a6ac1 100644 --- a/docs/extending-repositories.md +++ b/docs/extending-repositories.md @@ -54,8 +54,8 @@ end | Variable | Description | | -------- | ----------- | -| `{default.repository.root}` | The common root for all repositories. Currently defaults to `http://download.pivotal.io.s3.amazonaws.com`. -| `{platform}` | The platform that the application is running on. Currently detects `mountainlion`, `precise`, and `trusty`. +| `{default.repository.root}` | The common root for all repositories. Currently defaults to `https://java-buildpack.cloudfoundry.org`. +| `{platform}` | The platform that the application is running on. Currently detects `bionic`. | `{architecture}` | The architecture of the system as returned by Ruby. The value is typically one of `x86_64` or `x86`. ## Configuration @@ -95,5 +95,5 @@ In addition to declaring a specific versions to use, you can also specify a boun [`config/repository.yml`]: ../config/repository.yml [`JavaBuildpack::Repository::ConfiguredItem`]: ../lib/java_buildpack/repository/configured_item.rb [Configuration and Extension]: ../README.md#configuration-and-extension -[example]: http://download.pivotal.io.s3.amazonaws.com/openjdk/trusty/x86_64/index.yml +[example]: https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/index.yml diff --git a/docs/framework-google_stackdriver_debugger.md b/docs/framework-google_stackdriver_debugger.md index 63f911614c..adf4bca22a 100644 --- a/docs/framework-google_stackdriver_debugger.md +++ b/docs/framework-google_stackdriver_debugger.md @@ -39,5 +39,5 @@ The framework can be configured by modifying the [`config/google_stackdriver_deb [`config/google_stackdriver_debugger.yml`]: ../config/google_stackdriver_debugger.yml [Google Stackdriver Debugger Service]: https://cloud.google.com/debugger/ [repositories]: extending-repositories.md -[this listing]: http://download.pivotal.io.s3.amazonaws.com/google-stackdriver-debugger/trusty/x86_64/index.yml +[this listing]: https://java-buildpack.cloudfoundry.org/google-stackdriver-debugger/bionic/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/framework-google_stackdriver_profiler.md b/docs/framework-google_stackdriver_profiler.md index d290f3b491..bbc174efaa 100644 --- a/docs/framework-google_stackdriver_profiler.md +++ b/docs/framework-google_stackdriver_profiler.md @@ -39,5 +39,5 @@ The framework can be configured by modifying the [`config/google_stackdriver_pro [`config/google_stackdriver_profiler.yml`]: ../config/google_stackdriver_profiler.yml [Google Stackdriver Profiler Service]: https://cloud.google.com/profiler/ [repositories]: extending-repositories.md -[this listing]: http://download.pivotal.io.s3.amazonaws.com/google-stackdriver-profiler/trusty/x86_64/index.yml +[this listing]: https://java-buildpack.cloudfoundry.org/google-stackdriver-profiler/bionic/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/framework-your_kit_profiler.md b/docs/framework-your_kit_profiler.md index 5792b51915..45d98685a2 100644 --- a/docs/framework-your_kit_profiler.md +++ b/docs/framework-your_kit_profiler.md @@ -24,7 +24,7 @@ The framework can be configured by creating or modifying the [`config/your_kit_p | `enabled` | Whether to enable the YourKit Profiler | `port` | The port that the YourKit Profiler will listen on. Defaults to `10001`. | `repository_root` | The URL of the YourKit Profiler repository index ([details][repositories]). -| `version` | The version of the YourKit Profiler to use. Candidate versions can be found in the listings for [mountainlion][], [precise][], and [trusty][]. +| `version` | The version of the YourKit Profiler to use. Candidate versions can be found in the listings for [bionic][]. ## Creating SSH Tunnel After starting an application with the YourKit Profiler enabled, an SSH tunnel must be created to the container. To create that SSH container, execute the following command: @@ -40,9 +40,7 @@ Once the SSH tunnel has been created, your YourKit Profiler should connect to `l ![YourKit Configuration](framework-your_kit_profiler.png) [`config/your_kit_profiler.yml`]: ../config/your_kit_profiler.yml +[bionic]: https://download.run.pivotal.io/your-kit/bioni/x86_64/index.yml [Configuration and Extension]: ../README.md#configuration-and-extension -[mountainlion]: http://download.pivotal.io.s3.amazonaws.com/your-kit/mountainlion/x86_64/index.yml -[precise]: http://download.pivotal.io.s3.amazonaws.com/your-kit/precise/x86_64/index.yml [repositories]: extending-repositories.md -[trusty]: http://download.pivotal.io.s3.amazonaws.com/your-kit/trusty/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 0115bc8dc6..050de39b28 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -25,9 +25,9 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | Name | Description | ---- | ----------- | `jre.repository_root` | The URL of the OpenJDK repository index ([details][repositories]). -| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [mountainlion][], [trusty][] and [bionic][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [bionic][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [mountainlion][jvmkill-mountainlion] and [trusty][jvmkill-trusty]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -152,15 +152,12 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 ``` [`config/open_jdk_jre.yml`]: ../config/open_jdk_jre.yml +[bionic]: https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/index.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-mountainlion]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/mountainlion/x86_64/index.yml -[jvmkill-trusty]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/trusty/x86_64/index.yml +[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[mountainlion]: http://download.pivotal.io.s3.amazonaws.com/openjdk/mountainlion/x86_64/index.yml [OpenJDK]: http://openjdk.java.net [repositories]: extending-repositories.md -[trusty]: http://download.pivotal.io.s3.amazonaws.com/openjdk/trusty/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering [Volume Service]: https://docs.cloudfoundry.org/devguide/services/using-vol-services.html -[bionic]: http://download.pivotal.io.s3.amazonaws.com/openjdk/bionic/x86_64/index.yml diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index dd1d8cc98b..012a278465 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -43,7 +43,7 @@ To use Oracle JRE instead of OpenJDK without forking java-buildpack, set environ | `jre.repository_root` | The URL of the Oracle repository index ([details][repositories]). | `jre.version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [mountainlion][jvmkill-mountainlion] and [trusty][jvmkill-trusty]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -171,8 +171,7 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [`config/oracle_jre.yml`]: ../config/oracle_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-mountainlion]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/mountainlion/x86_64/index.yml -[jvmkill-trusty]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/trusty/x86_64/index.yml +[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [OpenJDK JRE]: jre-open_jdk_jre.md [Oracle]: http://www.oracle.com/technetwork/java/index.html diff --git a/docs/jre-sap_machine_jre.md b/docs/jre-sap_machine_jre.md index fd4bbe66d0..b91c9c4827 100644 --- a/docs/jre-sap_machine_jre.md +++ b/docs/jre-sap_machine_jre.md @@ -31,9 +31,9 @@ To use SapMachine JRE instead of OpenJDK without forking java-buildpack, set env | Name | Description | ---- | ----------- | `jre.repository_root` | The URL of the SapMachine repository index ([details][repositories]). -| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [mountainlion][] and [trusty][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [bionic][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [mountainlion][jvmkill-mountainlion] and [trusty][jvmkill-trusty]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -154,14 +154,12 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 ``` [`config/sap_machine_jre.yml`]: ../config/sap_machine_jre.yml +[bionic]: https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/index.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-mountainlion]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/mountainlion/x86_64/index.yml -[jvmkill-trusty]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/trusty/x86_64/index.yml +[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[mountainlion]: http://download.pivotal.io.s3.amazonaws.com/openjdk/mountainlion/x86_64/index.yml -[SapMachine]: https://sapmachine.io [repositories]: extending-repositories.md -[trusty]: http://download.pivotal.io.s3.amazonaws.com/openjdk/trusty/x86_64/index.yml +[SapMachine]: https://sapmachine.io [version syntax]: extending-repositories.md#version-syntax-and-ordering [Volume Service]: https://docs.cloudfoundry.org/devguide/services/using-vol-services.html diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index 7ff4c44fe7..3952679f6a 100644 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -34,7 +34,7 @@ To use Zulu JRE instead of OpenJDK without forking java-buildpack, set environme | `jre.repository_root` | The URL of the Zulu repository index ([details][repositories]). | `jre.version` | The version of Java runtime to use. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [mountainlion][jvmkill-mountainlion] and [trusty][jvmkill-trusty]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -163,8 +163,7 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [Azul Zulu]: https://www.azul.com/products/zulu/ [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-mountainlion]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/mountainlion/x86_64/index.yml -[jvmkill-trusty]: http://download.pivotal.io.s3.amazonaws.com/jvmkill/trusty/x86_64/index.yml +[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/rakelib/package.rb b/rakelib/package.rb index 2f10ade1e1..f449cc8d7d 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -33,7 +33,7 @@ def self.version BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze - PLATFORMS = %w[bionic trusty].freeze + PLATFORMS = %w[bionic].freeze STAGING_DIR = "#{BUILD_DIR}/staging" From cdb547f42bcffc1bd6c9f52b883a0c73dc06180d Mon Sep 17 00:00:00 2001 From: Gary Moore Date: Thu, 5 Sep 2019 14:46:27 -0400 Subject: [PATCH 540/812] Revert "Added default_server_name to Contrast Security Framework" This reverts commit cd849e8ba7d385946f4e99233c2525188fcb6e20. cd849e8 introduced a default server naming convention that was in conflict with the ways that others were setting server names. We would like to return to the server naming behavior as it was before cd849e8. We've discussed this change with owenfarrell. [resolves #744] Signed-off-by: Ben Hale --- config/contrast_security_agent.yml | 1 - docs/framework-contrast_security_agent.md | 1 - .../framework/contrast_security_agent.rb | 10 ---------- .../framework/contrast_security_agent_spec.rb | 10 ---------- 4 files changed, 22 deletions(-) diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index 45ee5972a4..e3fd6bf7db 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -16,5 +16,4 @@ # Configuration for the ContrastSecurity framework --- version: 3.+ -default_server_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh"):$CF_INSTANCE_INDEX repository_root: https://artifacts.contrastsecurity.com/agents/java diff --git a/docs/framework-contrast_security_agent.md b/docs/framework-contrast_security_agent.md index efd8fed8e3..ab6e5d4ea0 100644 --- a/docs/framework-contrast_security_agent.md +++ b/docs/framework-contrast_security_agent.md @@ -27,7 +27,6 @@ The framework can be configured by modifying the [`config/contrast_security_agen | Name | Description | ---- | ----------- | `repository_root` | The URL of the Contrast Security repository index ([details][repositories]). -| `default_server_name` | The default server name for this application in the Contrast dashboard. The default value is an expression that will be evaluated based on the `space_name`, `application_name`, and `instance_index` of the application. | | `version` | The version of Contrast Security to use. Candidate versions can be found in [this listing][]. [Contrast Security]: https://www.contrastsecurity.com diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index d79145fbfa..f2fc4ab379 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -40,7 +40,6 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.java_opts.add_system_property('contrast.override.appname', application_name) unless appname_exist? - @droplet.java_opts.add_system_property('contrast.server', server_name) unless server_exist? @droplet.java_opts .add_system_property('contrast.dir', '$TMPDIR') @@ -119,15 +118,6 @@ def contrast_config @droplet.sandbox + 'contrast.config' end - def server_exist? - @droplet.java_opts.any? { |java_opt| java_opt =~ /contrast.server/ } - end - - def server_name - @configuration['default_server_name'] || - "#{@application.details['space_name']}:#{@application.details['application_name']}:$CF_INSTANCE_INDEX" - end - def short_version "#{@version[0]}.#{@version[1]}.#{@version[2]}" end diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb index 9b6ae71819..d7a3287a80 100644 --- a/spec/java_buildpack/framework/contrast_security_agent_spec.rb +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -77,7 +77,6 @@ '=$PWD/.java-buildpack/contrast_security_agent/contrast.config') expect(java_opts).to include('-Dcontrast.dir=$TMPDIR') expect(java_opts).to include('-Dcontrast.override.appname=test-application-name') - expect(java_opts).to include('-Dcontrast.server=test-space-name:test-application-name:$CF_INSTANCE_INDEX') end it 'created contrast.config', @@ -96,15 +95,6 @@ expect(java_opts).not_to include('-Dcontrast.override.appname=test-application-name') end - it 'does not override server if there is an existing server' do - java_opts.add_system_property('contrast.server', 'NAME_ALREADY_OVERRIDDEN') - - component.release - - expect(java_opts).to include('-Dcontrast.server=NAME_ALREADY_OVERRIDDEN') - expect(java_opts).not_to include('-Dcontrast.server=test-space-name:test-application-name:$CF_INSTANCE_INDEX') - end - end end From ef8a4f5e51dc39ea5bcc4ee4f1db8ae936121bc1 Mon Sep 17 00:00:00 2001 From: Chen Harel Date: Mon, 16 Sep 2019 15:10:50 -0700 Subject: [PATCH 541/812] OverOps Updates This change updates the environment variables set via the OverOps framework. [resolves #745] Signed-off-by: Ben Hale --- docs/framework-takipi_agent.md | 14 ++++++++------ lib/java_buildpack/framework/takipi_agent.rb | 10 +++++----- spec/java_buildpack/framework/takipi_agent_spec.rb | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/framework-takipi_agent.md b/docs/framework-takipi_agent.md index 5dc7d17870..a4a9384f25 100644 --- a/docs/framework-takipi_agent.md +++ b/docs/framework-takipi_agent.md @@ -18,11 +18,13 @@ The credential payload can contain the following entries. | Name | Description | ---- | ----------- -| `secret_key` | (Optional) The agent installation key -| `collector_host` | (Optional) The remote collector hostname or IP -| `collector_port` | (Optional) the remote collector port +| `collector_host` | The remote collector hostname or IP +| `collector_port` | the remote collector port (TCP) +| `secret_key` | (DEPRECATED) The agent installation key for running collector alongside agent -Setting `secret_key` will run a local collector alongside the agent. Setting `collector_host` will use a remote collector. More information can be found in [OverOps Remote Collector][] +Setting `collector_host` and `collector_port` will connect to a remote collector. More information can be found in [OverOps Remote Collector][] + +(DEPRECATED)Setting `secret_key` will run a local collector alongside the agent. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. @@ -32,7 +34,7 @@ The framework can be configured by modifying the [`config/takipi_agent.yml`][] f | Name | Description | ---- | ----------- | `node_name_prefix` | Node name prefix, will be concatenated with `-` and instance index -| `application_name` | Override the Cloudfoundry default application name +| `application_name` | Override the CloudFoundry default application name ## Logs @@ -49,5 +51,5 @@ If your container is running out of memory and exited with status 137, then you [Configuration and Extension]: ../README.md#configuration-and-extension [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering -[OverOps Remote Collector]: https://support.overops.com/hc/en-us/articles/227109628-Remote-Daemon-Process- +[OverOps Remote Collector]: https://doc.overops.com/docs/install-collector [OverOps Service]: https://www.overops.com diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index d5abfd900f..b50deffa17 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -77,14 +77,14 @@ def application_name def config_env_vars(credentials) env = @droplet.environment_variables - secret_key = credentials['secret_key'] - env.add_environment_variable 'TAKIPI_SECRET_KEY', secret_key if secret_key - collector_host = credentials['collector_host'] - env.add_environment_variable 'TAKIPI_MASTER_HOST', collector_host if collector_host + env.add_environment_variable 'TAKIPI_COLLECTOR_HOST', collector_host if collector_host collector_port = credentials['collector_port'] - env.add_environment_variable 'TAKIPI_MASTER_PORT', collector_port if collector_port + env.add_environment_variable 'TAKIPI_COLLECTOR_PORT', collector_port if collector_port + + secret_key = credentials['secret_key'] + env.add_environment_variable 'TAKIPI_SECRET_KEY', secret_key if secret_key end def lib diff --git a/spec/java_buildpack/framework/takipi_agent_spec.rb b/spec/java_buildpack/framework/takipi_agent_spec.rb index bc55adef6d..e13dc8f80f 100644 --- a/spec/java_buildpack/framework/takipi_agent_spec.rb +++ b/spec/java_buildpack/framework/takipi_agent_spec.rb @@ -64,7 +64,7 @@ it 'updates user environment variables' do component.release - expect(environment_variables).to include('TAKIPI_MASTER_HOST=test-host') + expect(environment_variables).to include('TAKIPI_COLLECTOR_HOST=test-host') end context 'with secret key' do From dbd5103f15e2b6a310ba8aaf7538e3a217e106b0 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 24 Sep 2019 17:15:44 -0700 Subject: [PATCH 542/812] Remove Dyadic EKM Integration This change removes the Dyadic EKM integration. Signed-off-by: Ben Hale --- README.md | 1 - config/components.yml | 1 - config/dyadic_ekm_security_provider.yml | 19 --- .../framework-dyadic_ekm_security_provider.md | 65 -------- .../framework/dyadic_ekm_security_provider.rb | 130 ---------------- rakelib/versions_task.rb | 1 - .../ca.crt | 3 - .../client.conf | 5 - .../key.pem | 3 - .../stub-dyadic-ekm-security-provider.tar.gz | Bin 223 -> 0 bytes .../dyadic_ekm_security_provider_spec.rb | 142 ------------------ 11 files changed, 370 deletions(-) delete mode 100644 config/dyadic_ekm_security_provider.yml delete mode 100644 docs/framework-dyadic_ekm_security_provider.md delete mode 100644 lib/java_buildpack/framework/dyadic_ekm_security_provider.rb delete mode 100644 spec/fixtures/framework_dyadic_ekm_security_provider/ca.crt delete mode 100644 spec/fixtures/framework_dyadic_ekm_security_provider/client.conf delete mode 100644 spec/fixtures/framework_dyadic_ekm_security_provider/key.pem delete mode 100644 spec/fixtures/stub-dyadic-ekm-security-provider.tar.gz delete mode 100644 spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb diff --git a/README.md b/README.md index 6e213d4e3e..27dfb30ea4 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,6 @@ The buildpack supports extension through the use of Git repository forking. The * [Container Security Provider](docs/framework-container_security_provider.md) ([Configuration](docs/framework-container_security_provider.md#configuration)) * [Contrast Security Agent](docs/framework-contrast_security_agent.md) ([Configuration](docs/framework-contrast_security_agent.md#configuration)) * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) - * [Dyadic EKM Security Provider](docs/framework-dyadic_ekm_security_provider.md) ([Configuration](docs/framework-dyadic_ekm_security_provider.md#configuration)) * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) * [Elastic APM Agent](docs/framework-elastic_apm_agent.md) ([Configuration](docs/framework-elastic_apm_agent.md#configuration)) * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 99bd44226a..5a4acd1da7 100644 --- a/config/components.yml +++ b/config/components.yml @@ -48,7 +48,6 @@ frameworks: - "JavaBuildpack::Framework::ContainerSecurityProvider" - "JavaBuildpack::Framework::ContrastSecurityAgent" - "JavaBuildpack::Framework::Debug" - - "JavaBuildpack::Framework::DyadicEkmSecurityProvider" - "JavaBuildpack::Framework::DynatraceAppmonAgent" - "JavaBuildpack::Framework::DynatraceOneAgent" - "JavaBuildpack::Framework::ElasticApmAgent" diff --git a/config/dyadic_ekm_security_provider.yml b/config/dyadic_ekm_security_provider.yml deleted file mode 100644 index 555817606c..0000000000 --- a/config/dyadic_ekm_security_provider.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Configuration for the Luna Security Provider framework ---- -version: 1.+ -repository_root: https://repo.dyadicsec.com/cust/pcf diff --git a/docs/framework-dyadic_ekm_security_provider.md b/docs/framework-dyadic_ekm_security_provider.md deleted file mode 100644 index 59947bc458..0000000000 --- a/docs/framework-dyadic_ekm_security_provider.md +++ /dev/null @@ -1,65 +0,0 @@ -# Dyadic EKM Security Provider Framework -The Dyadic EKM Security Provider Framework causes an application to be automatically configured to work with a bound [Dyadic EKM][]. - - - - - - - - - - -
Detection CriterionExistence of a single bound Dyadic EKM Security Provider service. The existence of an Dyadic EKM Security service defined by the VCAP_SERVICES payload containing a service name, label or tag with dyadic as a substring. -
Tagsdyadic-security-provider=<version>
-Tags are printed to standard output by the buildpack detect script - -## User-Provided Service -When binding to the Dyadic EKM Security Provider using a user-provided service, it must have name or tag with `dyadic` in it. The credential payload can contain the following entries: - -| Name | Description -| ---- | ----------- -| `ca` | A PEM encoded CA certificate -| `key` | A PEM encoded client private key -| `recv_timeout` | A timeout for receiving data (in milliseconds) -| `retries` | The number of times to retry the connection -| `send_timeout` | A timeout for sending data (in milliseconds) -| `servers` | A comma delimited list of servers to connect to - -### Example Credentials Payload -``` -{ - "ca": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----", - "key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----", - "recv_timeout": 1000, - "retries": 5, - "send_timeout": 1000, - "servers": "test-server-1,test-server-2" -} -``` - -### Creating Credential Payload -In order to create the credentials payload, you should collapse the JSON payload to a single line and set it like the following - -``` -$ cf create-user-provided-service dyadic -p '{"ca":"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----","key":"-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----","recv_timeout":1000,"retries":5,"send_timeout":1000,"servers":"test-server-1,test-server-2"}' -``` - -## Configuration -For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. - -The framework can be configured by modifying the [`config/dyadic_security_provider.yml`][] file in the buildpack. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. - -| Name | Description -| ---- | ----------- -| `repository_root` | The URL of the Dyadic Security Provider repository index ([details][repositories]). -| `version` | Version of the Dyadic Security Provider to use. - -### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/dyadic_security_provider` directory in the buildpack fork. - -[`config/dyadic_security_provider.yml`]: ../config/dyadic_ekm_security_provider.yml -[Dyadic EKM]: https://www.dyadicsec.com/key_management/ -[Configuration and Extension]: ../README.md#configuration-and-extension -[repositories]: extending-repositories.md -[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb b/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb deleted file mode 100644 index 53f30b74a2..0000000000 --- a/lib/java_buildpack/framework/dyadic_ekm_security_provider.rb +++ /dev/null @@ -1,130 +0,0 @@ -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'fileutils' -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/framework' -require 'java_buildpack/util/qualify_path' - -module JavaBuildpack - module Framework - - # Encapsulates the functionality for enabling zero-touch Dyadic EKM Java Security Provider support. - class DyadicEkmSecurityProvider < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Util - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download_tar - setup_ext_dir - - @droplet.copy_resources - @droplet.security_providers << 'com.dyadicsec.provider.DYCryptoProvider' - @droplet.root_libraries << dyadic_jar if @droplet.java_home.java_9_or_later? - - credentials = @application.services.find_service(FILTER, 'ca', 'key', 'recv_timeout', 'retries', 'send_timeout', - 'servers')['credentials'] - write_files(credentials) - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release - @droplet.environment_variables - .add_environment_variable 'LD_LIBRARY_PATH', @droplet.sandbox + 'usr/lib' - - if @droplet.java_home.java_9_or_later? - @droplet.root_libraries << dyadic_jar - else - @droplet.extension_directories << ext_dir - end - end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - @application.services.one_service? FILTER, 'ca', 'key', 'recv_timeout', 'retries', 'send_timeout', 'servers' - end - - private - - FILTER = /dyadic/.freeze - - private_constant :FILTER - - def cert_file - @droplet.sandbox + 'etc/dsm/ca.crt' - end - - def conf_file - @droplet.sandbox + 'etc/dsm/client.conf' - end - - def dyadic_jar - @droplet.sandbox + 'usr/lib/dsm/dsm-advapi-1.0.jar' - end - - def ext_dir - @droplet.sandbox + 'ext' - end - - def key_file - @droplet.sandbox + 'etc/dsm/key.pem' - end - - def setup_ext_dir - FileUtils.mkdir ext_dir - FileUtils.ln_s dyadic_jar.relative_path_from(ext_dir), ext_dir, force: true - end - - def write_cert(cert) - FileUtils.mkdir_p cert_file.parent - cert_file.open(File::CREAT | File::WRONLY) do |f| - f.write "#{cert}\n" - end - end - - def write_conf(servers, send_timeout, recv_timeout, retries) - FileUtils.mkdir_p conf_file.parent - conf_file.open(File::CREAT | File::WRONLY) do |f| - f.write <<~CONFIG - servers = #{servers} - send_timeout = #{send_timeout} - recv_timeout = #{recv_timeout} - retries = #{retries} - ha_mode_standby = 1 - CONFIG - end - end - - def write_files(credentials) - write_key credentials['key'] - write_cert credentials['ca'] - write_conf credentials['servers'], credentials['send_timeout'], credentials['recv_timeout'], - credentials['retries'] - end - - def write_key(key) - FileUtils.mkdir_p key_file.parent - key_file.open(File::CREAT | File::WRONLY) do |f| - f.write "#{key}\n" - end - end - - end - end -end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index eebfc338cd..c3e63c2ee6 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -60,7 +60,6 @@ def initialize 'container_customizer' => 'Spring Boot Container Customizer', 'container_security_provider' => 'Container Security Provider', 'contrast_security_agent' => 'Contrast Security Agent', - 'dyadic_ekm_security_provider' => 'Dyadic EKM Security Provider', 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', 'dynatrace_one_agent' => 'Dynatrace OneAgent', 'elastic_apm_agent' => 'Elastic APM Agent', diff --git a/spec/fixtures/framework_dyadic_ekm_security_provider/ca.crt b/spec/fixtures/framework_dyadic_ekm_security_provider/ca.crt deleted file mode 100644 index 40769aae71..0000000000 --- a/spec/fixtures/framework_dyadic_ekm_security_provider/ca.crt +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN CERTIFICATE----- -test-client-cert ------END CERTIFICATE----- diff --git a/spec/fixtures/framework_dyadic_ekm_security_provider/client.conf b/spec/fixtures/framework_dyadic_ekm_security_provider/client.conf deleted file mode 100644 index 57ca31a3bb..0000000000 --- a/spec/fixtures/framework_dyadic_ekm_security_provider/client.conf +++ /dev/null @@ -1,5 +0,0 @@ -servers = server-1,server-2 -send_timeout = 3 -recv_timeout = 1 -retries = 2 -ha_mode_standby = 1 diff --git a/spec/fixtures/framework_dyadic_ekm_security_provider/key.pem b/spec/fixtures/framework_dyadic_ekm_security_provider/key.pem deleted file mode 100644 index 019359d6ba..0000000000 --- a/spec/fixtures/framework_dyadic_ekm_security_provider/key.pem +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -test-client-private-key ------END RSA PRIVATE KEY----- diff --git a/spec/fixtures/stub-dyadic-ekm-security-provider.tar.gz b/spec/fixtures/stub-dyadic-ekm-security-provider.tar.gz deleted file mode 100644 index 73bb20f14a531e6067a11c3e097c0d8926b9503e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 223 zcmV<503iP#iwFRVWm#AN1MSl73W6{ghG7q7C!oFW+~(oLOeMo2{OI^wDM69KLWSzN z{4sF*vF%>g9K&5z=BIYck=z7JAfiNTaUV@Tl2rXT5FC>ZBi>_&H z?Y5HcZIw@~bIXciVtzQsWBd}?bN{ZX=YIqK{gsvy{nzlOe^sXQz5)OKS|)`4YZ&S8 ze$V#?y!y-7^*5vq`mbT4|82@<7ke&4jwm{~Yx<1452KVvf5~LxK+vow9r5S=0RR91 Z0000000000007`OTmh~##3}$N002GcZN&fp diff --git a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb b/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb deleted file mode 100644 index bb3ceca9eb..0000000000 --- a/spec/java_buildpack/framework/dyadic_ekm_security_provider_spec.rb +++ /dev/null @@ -1,142 +0,0 @@ -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/framework/dyadic_ekm_security_provider' - -describe JavaBuildpack::Framework::DyadicEkmSecurityProvider do - include_context 'with component help' - - it 'does not detect without dyadic-n/a service' do - expect(component.detect).to be_nil - end - - context do - - before do - allow(services).to receive(:one_service?) - .with(/dyadic/, 'ca', 'key', 'recv_timeout', 'retries', 'send_timeout', 'servers') - .and_return(true) - - allow(services).to receive(:find_service).and_return( - 'credentials' => { - 'ca' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", - 'key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----", - 'recv_timeout' => 1, - 'retries' => 2, - 'send_timeout' => 3, - 'servers' => 'server-1,server-2' - } - ) - end - - it 'detects with dyadic-n/a service' do - expect(component.detect).to eq("dyadic-ekm-security-provider=#{version}") - end - - it 'unpacks the dyadic tar', - cache_fixture: 'stub-dyadic-ekm-security-provider.tar.gz' do - - component.compile - - expect(sandbox + 'usr/lib/dsm/dsm-advapi-1.0.jar').to exist - expect(sandbox + 'usr/lib').to exist - end - - it 'write certificate and key files', - cache_fixture: 'stub-dyadic-ekm-security-provider.tar.gz' do - - component.compile - - expect(sandbox + 'etc/dsm/ca.crt').to exist - expect(sandbox + 'etc/dsm/key.pem').to exist - - check_file_contents(sandbox + 'etc/dsm/ca.crt', - 'spec/fixtures/framework_dyadic_ekm_security_provider/ca.crt') - check_file_contents(sandbox + 'etc/dsm/key.pem', - 'spec/fixtures/framework_dyadic_ekm_security_provider/key.pem') - end - - it 'writes configuration', - cache_fixture: 'stub-dyadic-ekm-security-provider.tar.gz' do - - component.compile - - expect(sandbox + 'etc/dsm/client.conf').to exist - check_file_contents(sandbox + 'etc/dsm/client.conf', - 'spec/fixtures/framework_dyadic_ekm_security_provider/client.conf') - end - - it 'updates environment variables' do - component.release - expect(environment_variables).to include('LD_LIBRARY_PATH=$PWD/.java-buildpack/' \ - 'dyadic_ekm_security_provider/usr/lib') - end - - it 'adds security provider', - cache_fixture: 'stub-dyadic-ekm-security-provider.tar.gz' do - - component.compile - - expect(security_providers.last).to eq('com.dyadicsec.provider.DYCryptoProvider') - end - - it 'adds extension directory' do - component.release - - expect(extension_directories).to include(droplet.sandbox + 'ext') - end - - context do - - let(:java_home_delegate) do - delegate = JavaBuildpack::Component::MutableJavaHome.new - delegate.root = app_dir + '.test-java-home' - delegate.version = JavaBuildpack::Util::TokenizedVersion.new('9.0.0') - - delegate - end - - it 'adds JAR to classpath during compile in Java 9', - cache_fixture: 'stub-dyadic-ekm-security-provider.tar.gz' do - - component.compile - - expect(root_libraries).to include(droplet.sandbox + 'usr/lib/dsm/dsm-advapi-1.0.jar') - end - - it 'adds JAR to classpath during release in Java 9' do - component.release - - expect(root_libraries).to include(droplet.sandbox + 'usr/lib/dsm/dsm-advapi-1.0.jar') - end - - it 'adds does not add extension directory in Java 9' do - component.release - - expect(extension_directories).not_to include(droplet.sandbox + 'ext') - end - - end - - def check_file_contents(actual, expected) - expect(File.read(actual)).to eq File.read(expected) - end - - end -end From 85b6ed0c4f6f71bcea8c161876ab49ba6cfc7c4b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 3 Oct 2019 08:51:39 -0700 Subject: [PATCH 543/812] Disable Metric Writer by Default This change disables the metric writer by default. [resolves #748] Signed-off-by: Ben Hale --- config/metric_writer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/metric_writer.yml b/config/metric_writer.yml index e13aa4b79c..7a96b43a96 100644 --- a/config/metric_writer.yml +++ b/config/metric_writer.yml @@ -17,4 +17,4 @@ --- version: 3.+ repository_root: "{default.repository.root}/metric-writer" -enabled: true +enabled: false From 6851102c78cf62eb65bdf306f31da3c9e3854ef6 Mon Sep 17 00:00:00 2001 From: jeffaholmes Date: Fri, 6 Sep 2019 17:04:11 -0700 Subject: [PATCH 544/812] AppDynamics Node Name Prefix Environment Variable This change includes adds an environment variable that allows a user to specify the prefix applied to an AppDynamics Node Name. [resolves #749] Signed-off-by: Ben Hale --- config/app_dynamics_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 00abe7fbef..20eb279456 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -18,6 +18,6 @@ version: 4.+ repository_root: https://packages.appdynamics.com/java default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") -default_node_name: $(jq -r -n "$VCAP_APPLICATION | .application_name + \":$CF_INSTANCE_INDEX\"") +default_node_name: $(jq -r -n "\"$APPD_CF_NODE_PREFIX\" + ($VCAP_APPLICATION | .application_name) + \":$CF_INSTANCE_INDEX\"") default_tier_name: default_unique_host_name: $(jq -r -n "$VCAP_APPLICATION | .application_id + \":$CF_INSTANCE_INDEX\"") From a1b5dcc5d3e9dbee18460b53fd651cbdbb9ad71d Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 14 Oct 2019 15:04:57 -0700 Subject: [PATCH 545/812] Dependency Updates Signed-off-by: Ben Hale --- .idea/codeStyles/Project.xml | 1 + Gemfile.lock | 46 +++++++++---------- java-buildpack.iml | 30 ++++++------ lib/java_buildpack/buildpack_version.rb | 1 - spec/java_buildpack/jre/open_jdk_like_spec.rb | 6 +-- .../util/format_duration_spec.rb | 46 ++++++++----------- 6 files changed, 62 insertions(+), 68 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index c688e58fe5..45fd68eacd 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -5,6 +5,7 @@
diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index b9a2e87c9c..ef19274751 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -64,7 +64,6 @@ def initialize(should_log = true) # @return [Hash] a representation of the buildpack version def to_hash h = {} - h['hash'] = @hash if @hash h['offline'] = @offline if @offline h['remote'] = @remote if @remote diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index ec75870fd0..f2cc912abc 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -31,9 +31,9 @@ let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } - let(:version_7) { VERSION_7 = JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } + let(:version_7) { JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } - let(:version_8) { VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } + let(:version_8) { JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } let(:configuration) do { 'jre' => jre_configuration, @@ -99,7 +99,7 @@ def supports? end def sub_configuration_context(configuration) - c = context.clone + c = context.clone c[:configuration] = configuration c end diff --git a/spec/java_buildpack/util/format_duration_spec.rb b/spec/java_buildpack/util/format_duration_spec.rb index 4cc15adebf..6e084afaa5 100644 --- a/spec/java_buildpack/util/format_duration_spec.rb +++ b/spec/java_buildpack/util/format_duration_spec.rb @@ -20,41 +20,35 @@ describe 'duration' do # rubocop:disable RSpec/DescribeClass + let(:millisecond) { 0.001 } + let(:tenth) { 100 * millisecond } + let(:second) { 10 * tenth } + let(:minute) { 60 * second } + let(:hour) { 60 * minute } + it 'displays seconds' do - expect_time_string '0.0s', MILLISECOND - expect_time_string '0.1s', TENTH - expect_time_string '1.0s', SECOND - expect_time_string '1.1s', SECOND + TENTH - expect_time_string '1.1s', SECOND + TENTH + MILLISECOND + expect_time_string '0.0s', millisecond + expect_time_string '0.1s', tenth + expect_time_string '1.0s', second + expect_time_string '1.1s', second + tenth + expect_time_string '1.1s', second + tenth + millisecond end it 'displays minutes' do - expect_time_string '1m 0s', MINUTE - expect_time_string '1m 1s', MINUTE + SECOND - expect_time_string '1m 1s', MINUTE + SECOND + TENTH - expect_time_string '1m 1s', MINUTE + SECOND + TENTH + MILLISECOND + expect_time_string '1m 0s', minute + expect_time_string '1m 1s', minute + second + expect_time_string '1m 1s', minute + second + tenth + expect_time_string '1m 1s', minute + second + tenth + millisecond end it 'displays hours' do - expect_time_string '1h 0m', HOUR - expect_time_string '1h 1m', HOUR + MINUTE - expect_time_string '1h 1m', HOUR + MINUTE + SECOND - expect_time_string '1h 1m', HOUR + MINUTE + SECOND + TENTH - expect_time_string '1h 1m', HOUR + MINUTE + SECOND + TENTH + MILLISECOND + expect_time_string '1h 0m', hour + expect_time_string '1h 1m', hour + minute + expect_time_string '1h 1m', hour + minute + second + expect_time_string '1h 1m', hour + minute + second + tenth + expect_time_string '1h 1m', hour + minute + second + tenth + millisecond end - private - - MILLISECOND = 0.001 - - TENTH = 100 * MILLISECOND - - SECOND = 10 * TENTH - - MINUTE = 60 * SECOND - - HOUR = 60 * MINUTE - def expect_time_string(expected, time) expect(time.duration).to eq(expected) end From 4a8b92ba2d165594201855d815ce3e9d1fb532cc Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 16 Oct 2019 11:47:51 -0700 Subject: [PATCH 546/812] Include Java 13 Signed-off-by: Ben Hale --- rakelib/dependency_cache_task.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 7b6f7633b6..90641f4028 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -132,7 +132,7 @@ def configurations(component_id, configuration, sub_component_id = nil) if component_id == 'open_jdk_jre' && sub_component_id == 'jre' c1 = configuration.clone - c1['version'] = '12.+' + c1['version'] = '13.+' configurations << c1 end From a2dd394b175725e76f0e0be4ad0591c54abd7ea8 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Thu, 17 Oct 2019 11:36:13 -0700 Subject: [PATCH 547/812] More Java 13 Updates Signed-off-by: Ben Hale --- rakelib/versions_task.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index c3e63c2ee6..6e0aa83b88 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -72,7 +72,7 @@ def initialize 'jprofiler_profiler' => 'JProfiler Profiler', 'jre' => 'OpenJDK JRE', 'jre-11' => 'OpenJDK JRE 11', - 'jre-12' => 'OpenJDK JRE 12', + 'jre-13' => 'OpenJDK JRE 13', 'jrebel_agent' => 'JRebel Agent', 'jvmkill_agent' => 'jvmkill Agent', 'lifecycle_support' => 'Tomcat Lifecycle Support', @@ -167,8 +167,8 @@ def configurations(component_id, configuration, sub_component_id = nil) if component_id == 'open_jdk_jre' && sub_component_id == 'jre' c1 = configuration.clone - c1['sub_component_id'] = 'jre-12' - c1['version'] = '12.+' + c1['sub_component_id'] = 'jre-13' + c1['version'] = '13.+' configurations << c1 end From 18d37aa7b7cc31fedd5a2a38176a694085ac0473 Mon Sep 17 00:00:00 2001 From: Moshe Apelbaum Date: Mon, 20 May 2019 18:48:22 +0300 Subject: [PATCH 548/812] Synopsys Seeker Support This change adds support for Synposys Seeker. Detection is based on the existing of a 'seeker' service, and contributes the agent as downloaded from the server. [#741] Signed-off-by: Ben Hale --- README.md | 3 +- config/components.yml | 1 + config/seeker_agent.yml | 20 ++ .../framework/seeker_security_provider.rb | 177 +++++++++++++++++ spec/fixtures/seeker-java-agent.zip | Bin 0 -> 414 bytes spec/fixtures/sensor.zip | Bin 0 -> 762 bytes .../framework/seeker_security_agent_spec.rb | 184 ++++++++++++++++++ 7 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 config/seeker_agent.yml create mode 100644 lib/java_buildpack/framework/seeker_security_provider.rb create mode 100644 spec/fixtures/seeker-java-agent.zip create mode 100644 spec/fixtures/sensor.zip create mode 100644 spec/java_buildpack/framework/seeker_security_agent_spec.rb diff --git a/README.md b/README.md index 27dfb30ea4..d83cfbc90d 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,9 @@ The buildpack supports extension through the use of Git repository forking. The * [Metric Writer](docs/framework-metric_writer.md) ([Configuration](docs/framework-metric_writer.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) - * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) + * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) * [Riverbed AppInternals Agent](docs/framework-riverbed_appinternals_agent.md) ([Configuration](docs/framework-riverbed_appinternals_agent.md#configuration)) + * [Seeker Security Provider](docs/framework-seeker_security_provider.md) ([Configuration](docs/framework-seeker_security_provider.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) * [Spring Insight](docs/framework-spring_insight.md) * [SkyWalking Agent](docs/framework-sky_walking_agent.md) ([Configuration](docs/framework-sky_walking_agent.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 5a4acd1da7..2221f6fec9 100644 --- a/config/components.yml +++ b/config/components.yml @@ -66,6 +66,7 @@ frameworks: - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::ProtectAppSecurityProvider" - "JavaBuildpack::Framework::RiverbedAppinternalsAgent" + - "JavaBuildpack::Framework::SeekerSecurityProvider" - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::SkyWalkingAgent" diff --git a/config/seeker_agent.yml b/config/seeker_agent.yml new file mode 100644 index 0000000000..6861754749 --- /dev/null +++ b/config/seeker_agent.yml @@ -0,0 +1,20 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Seeker Agent framework +--- +version: 0.+ +repository_root: path to website with index.yml +default_agent_name: $(ruby -e "require 'json' ; puts JSON.parse(ENV['VCAP_APPLICATION'])['application_name']") diff --git a/lib/java_buildpack/framework/seeker_security_provider.rb b/lib/java_buildpack/framework/seeker_security_provider.rb new file mode 100644 index 0000000000..5b395b9639 --- /dev/null +++ b/lib/java_buildpack/framework/seeker_security_provider.rb @@ -0,0 +1,177 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2017 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/logging/logger_factory' +require 'java_buildpack/component/base_component' +require 'java_buildpack/framework' +require 'fileutils' +require 'net/http' +require 'json' +require 'date' +require 'cgi' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Seeker support. + class SeekerSecurityProvider < JavaBuildpack::Component::BaseComponent + # Creates an instance + # + # @param [Hash] context a collection of utilities used the component + def initialize(context) + super(context) + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger SeekerSecurityProvider + end + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + @application.services.one_service? FILTER + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + + def compile + @logger.info { 'Seeker buildpack compile stage start' } + credentials = fetch_credentials + @logger.info { "Credentials #{credentials}" } + assert_configuration_valid(credentials) + if should_download_sensor(credentials[ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY]) + fetch_agent_within_sensor(credentials) + else + fetch_agent_direct(credentials) + end + @droplet.copy_resources + end + + # extract seeker relevant configuration as map + def fetch_credentials + service = @application.services.find_service FILTER + service['credentials'] + end + + # verify required agent configuration is present + def assert_configuration_valid(credentials) + mandatory_config_keys = + [ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY, SENSOR_HOST_SERVICE_CONFIG_KEY, + SENSOR_PORT_SERVICE_CONFIG_KEY, SEEKER_SERVER_URL_CONFIG_KEY] + mandatory_config_keys.each do |config_key| + raise "'#{config_key}' credential must be set" unless credentials[config_key] + end + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @logger.info { 'Seeker buildpack release stage start' } + credentials = fetch_credentials + @droplet.java_opts.add_javaagent(@droplet.sandbox + 'seeker-agent.jar') + @droplet.environment_variables + .add_environment_variable('SEEKER_SENSOR_HOST', credentials[SENSOR_HOST_SERVICE_CONFIG_KEY]) + .add_environment_variable('SEEKER_SENSOR_HTTP_PORT', credentials[SENSOR_PORT_SERVICE_CONFIG_KEY]) + .add_environment_variable('SEEKER_SERVER_URL', credentials[SEEKER_SERVER_URL_CONFIG_KEY]) + end + + # JSON key for the host of the seeker sensor + SENSOR_HOST_SERVICE_CONFIG_KEY = 'sensor_host' + + # JSON key for the port of the seeker sensor + SENSOR_PORT_SERVICE_CONFIG_KEY = 'sensor_port' + # JSON key for the address of seeker sensor + SEEKER_SERVER_URL_CONFIG_KEY = 'seeker_server_url' + + # Enterprise server url, for example: `https://seeker-server.com:8082` + ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY = 'enterprise_server_url' + + # Relative path of the sensor zip + SENSOR_ZIP_RELATIVE_PATH_AT_ENTERPRISE_SERVER = 'rest/ui/installers/binaries/LINUX' + + # Relative path of the Java agent jars after Sensor extraction + AGENT_JARS_PATH = 'inline/agents/java/*' + + # Relative path of the agent zip + AGENT_PATH = '/rest/api/latest/installers/agents/binaries/JAVA' + + # Version details of Seekers server REST API path + SEEKER_VERSION_API = '/rest/api/version' + + # seeker service name identifier + FILTER = /seeker/.freeze + + private_constant :SENSOR_HOST_SERVICE_CONFIG_KEY, :SENSOR_PORT_SERVICE_CONFIG_KEY, + :ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY, :SENSOR_ZIP_RELATIVE_PATH_AT_ENTERPRISE_SERVER, + :AGENT_JARS_PATH, :AGENT_PATH, :SEEKER_VERSION_API + + private + + def should_download_sensor(server_base_url) + json_response = get_seeker_version_details(server_base_url) + @logger.debug { "Seeker server response for version WS: #{json_response}" } + seeker_version_response = JSON.parse(json_response) + seeker_version = seeker_version_response['version'] + version_prefix = seeker_version[0, 7] + last_seeker_version_without_agent_direct_download_date = Date.parse('2018.05.01') + @logger.info { "Current Seeker version #{version_prefix}" } + current_seeker_version = Date.parse(version_prefix + '.01') + current_seeker_version <= last_seeker_version_without_agent_direct_download_date + end + + def get_seeker_version_details(server_base_url) + uri = URI.parse(server_base_url) + http = Net::HTTP.new(uri.host, uri.port) + if uri.scheme == 'https' + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + http.use_ssl = true + end + http_response = http.request_get(SEEKER_VERSION_API) + http_response.body + end + + def agent_direct_link(credentials) + URI.join(credentials[ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY], AGENT_PATH).to_s + end + + def fetch_agent_direct(credentials) + @logger.info { 'Trying to download agent directly...' } + java_agent_zip_uri = agent_direct_link(credentials) + download_agent(java_agent_zip_uri) + end + + def download_agent(java_agent_zip_uri) + @logger.debug { "Before downloading Agent from: #{java_agent_zip_uri}" } + download_zip('', java_agent_zip_uri, false, @droplet.sandbox) + end + + def fetch_agent_within_sensor(credentials) + @logger.info { 'Trying to download sensor...' } + seeker_tmp_dir = @droplet.sandbox + 'seeker_tmp_sensor' + shell "rm -rf #{seeker_tmp_dir}" + sensor_direct_link = sensor_direct_link(credentials) + @logger.debug { "Before downloading Sensor from: #{sensor_direct_link}" } + download_zip('', sensor_direct_link, + false, seeker_tmp_dir, 'SensorInstaller.zip') + inner_jar_file = seeker_tmp_dir + 'SeekerInstaller.jar' + # Unzip only the java agent - to save time + shell "unzip -j #{inner_jar_file} #{AGENT_JARS_PATH} -d #{@droplet.sandbox} 2>&1" + shell "rm -rf #{seeker_tmp_dir}" + end + + def sensor_direct_link(credentials) + enterprise_server_uri = URI.parse(credentials[ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY].strip) + URI.join(enterprise_server_uri, SENSOR_ZIP_RELATIVE_PATH_AT_ENTERPRISE_SERVER).to_s + end + end + end +end diff --git a/spec/fixtures/seeker-java-agent.zip b/spec/fixtures/seeker-java-agent.zip new file mode 100644 index 0000000000000000000000000000000000000000..702055054301ef35f6338311a2571043affb139e GIT binary patch literal 414 zcmWIWW@Zs#-~hsahKoK7P{0VJ1sD_eGrvPtOHjpt)KzI;H I9|v(50MwpZEC2ui literal 0 HcmV?d00001 diff --git a/spec/fixtures/sensor.zip b/spec/fixtures/sensor.zip new file mode 100644 index 0000000000000000000000000000000000000000..0e38bec5fcbfa666199169ea3b18f9746a42fe08 GIT binary patch literal 762 zcmWIWW@Zs#-~hryY43d)pkOZx1A{Pw0z+_WYIbUoXI^nhVopwKkzQ6}QD_J+1N$CH z?`Rk9*0WO>2NzyKz=KcuBSOiFn0AR&Rf`te}~79Spg158Iw{@nTN3=d<0sZmDO zjYbP&eRX4fQP-Py0zy)2I8r-buB=o&swybn_n?&-di9j0fhCO~78!{L*#eLUkSzy!00x#co@Znr+B*T>tRUAjFahCqAg#*;;sF4c CpY>Y+ literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/seeker_security_agent_spec.rb b/spec/java_buildpack/framework/seeker_security_agent_spec.rb new file mode 100644 index 0000000000..71ee1a973a --- /dev/null +++ b/spec/java_buildpack/framework/seeker_security_agent_spec.rb @@ -0,0 +1,184 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/seeker_security_provider' + +describe JavaBuildpack::Framework::SeekerSecurityProvider do + include_context 'with component help' + + let(:configuration) do + { 'some_property' => nil } + end + + it 'does not detect without seeker service' do + expect(component.detect).to be_falsey + end + + context do + + let(:credentials) { {} } + + before do + allow(services).to receive(:one_service?).with(/seeker/).and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => credentials) + end + + it 'detects with seeker service' do + expect(component.detect).to be_truthy + end + + context do + let(:credentials) do + { 'sensor_port' => '9911', + 'sensor_host' => 'localhost' } + end + + it 'raises error if `enterprise_server_url` not specified' do + expect { component.compile }.to raise_error(/'enterprise_server_url' credential must be set/) + end + end + + context do + let(:credentials) do + { 'sensor_port' => '9911', + 'sensor_host' => 'localhost', + 'enterprise_server_url' => 'some-url' } + end + + it 'raises error if `seeker_server_url` not specified' do + expect { component.compile }.to raise_error(/'seeker_server_url' credential must be set/) + end + end + + context do + let(:credentials) do + { 'enterprise_server_url' => 'http://10.120.9.117:8082', + 'sensor_port' => '9911' } + end + + it 'raises error if `sensor_host` not specified' do + expect { component.compile }.to raise_error(/'sensor_host' credential must be set/) + end + + end + + context do + let(:credentials) do + { 'enterprise_server_url' => 'http://10.120.9.117:8082', + 'sensor_host' => 'localhost' } + end + + it 'raises error if `sensor_port` not specified' do + expect { component.compile }.to raise_error(/'sensor_port' credential must be set/) + end + + end + + context do + let(:credentials) do + { 'enterprise_server_url' => 'http://10.120.9.117:8082', + 'seeker_server_url' => 'http://10.120.9.117:9911', + 'sensor_host' => 'localhost', + 'sensor_port' => '9911' } + end + + before do + allow(component).to receive(:agent_direct_link).with(credentials).and_return('test-uri') + end + + it 'expands Seeker agent zip for agent direct download', + cache_fixture: 'seeker-java-agent.zip' do + + allow(component).to receive(:should_download_sensor).and_return(false) + component.compile + + expect(sandbox + 'seeker-agent.jar').to exist + + end + it 'Chooses downloading the agent for Seeker versions newer than 2018.05', + cache_fixture: 'seeker-java-agent.zip' do + agent_download_expected_dates = ['2018.06', '2018.07', '2018.08', '2018.09', '2018.10', '2018.11', + '2018.12', '2019.01', '2019.02', '2019.03', '2019.04', '2019.05'] + agent_download_expected_dates.each do |seeker_version| + json_version_mock_response = + ["{\"publicName\":\"Seeker Enterprise Server\",\"version\":\"#{seeker_version}\"", + ',"buildNumber":"20121550","scmBranch":"origin/release/v2018.06","scmRevision":"809"}'].join(' ') + allow(component).to receive(:get_seeker_version_details) + .with(credentials['enterprise_server_url']).and_return(json_version_mock_response) + allow(component).to receive(:download_agent) + component.compile + end + + end + it 'updates JAVA_OPTS' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/seeker_security_provider/seeker-agent.jar') + end + + end + + context do + let(:credentials) do + { 'enterprise_server_url' => 'http://10.120.9.117:8082', + 'seeker_server_url' => 'http://10.120.9.117:9911', + 'sensor_host' => 'localhost', + 'sensor_port' => '9911' } + end + + before do + allow(component).to receive(:sensor_direct_link).with(credentials).and_return('test-uri') + end + + it 'expands Seeker agent from within sensor zip', + cache_fixture: 'sensor.zip' do + allow(component).to receive(:should_download_sensor).and_return(true) + component.compile + + expect(sandbox + 'seeker-agent.jar').to exist + + end + + it 'Chooses downloading the sensor for Seeker versions older than 2018.05 (including 2018.05)', + cache_fixture: 'sensor.zip' do + sensor_download_expected_dates = ['2018.05', '2018.04', '2018.03', '2018.02', '2018.01', '2017.12', '2017.11', + '2017.10', '2017.09', '2017.08', '2017.05', + '2017.04', '2017.03', '2017.02', '2017.01'] + sensor_download_expected_dates.each do |seeker_version| + json_version_mock_response = + ["{\"publicName\":\"Seeker Enterprise Server\",\"version\":\"#{seeker_version}\"", + ',"buildNumber":"20121550","scmBranch":"origin/release/v2018.06","scmRevision":"809"}'].join(' ') + allow(component).to receive(:get_seeker_version_details) + .with(credentials['enterprise_server_url']).and_return(json_version_mock_response) + allow(component).to receive(:fetch_agent_within_sensor).with(credentials) + component.compile + end + + end + + it 'updates JAVA_OPTS' do + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/seeker_security_provider/seeker-agent.jar') + end + + end + end + +end From 8ad0be026d46295d72dd5b7c43a736ed17e88592 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Wed, 30 Oct 2019 14:13:21 -0700 Subject: [PATCH 549/812] Polishing [resolves #741] Signed-off-by: Ben Hale --- .idea/dictionaries/bhale.xml | 1 + README.md | 2 +- config/seeker_agent.yml | 20 --- docs/framework-seeker-security-provider.md | 24 +++ .../framework/seeker_security_provider.rb | 139 +++------------- spec/fixtures/sensor.zip | Bin 762 -> 0 bytes ...r-java-agent.zip => stub-seeker-agent.zip} | Bin .../framework/seeker_security_agent_spec.rb | 155 ++---------------- 8 files changed, 69 insertions(+), 272 deletions(-) delete mode 100644 config/seeker_agent.yml create mode 100644 docs/framework-seeker-security-provider.md delete mode 100644 spec/fixtures/sensor.zip rename spec/fixtures/{seeker-java-agent.zip => stub-seeker-agent.zip} (100%) diff --git a/.idea/dictionaries/bhale.xml b/.idea/dictionaries/bhale.xml index 9d1633adc0..9d6586b479 100644 --- a/.idea/dictionaries/bhale.xml +++ b/.idea/dictionaries/bhale.xml @@ -108,6 +108,7 @@ stubframework stubjre submodules + synopsys takipi tasklib tcpclient diff --git a/README.md b/README.md index d83cfbc90d..2f7045e0cd 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ The buildpack supports extension through the use of Git repository forking. The * [Metric Writer](docs/framework-metric_writer.md) ([Configuration](docs/framework-metric_writer.md#configuration)) * [New Relic Agent](docs/framework-new_relic_agent.md) ([Configuration](docs/framework-new_relic_agent.md#configuration)) * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) - * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) + * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) * [Riverbed AppInternals Agent](docs/framework-riverbed_appinternals_agent.md) ([Configuration](docs/framework-riverbed_appinternals_agent.md#configuration)) * [Seeker Security Provider](docs/framework-seeker_security_provider.md) ([Configuration](docs/framework-seeker_security_provider.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) diff --git a/config/seeker_agent.yml b/config/seeker_agent.yml deleted file mode 100644 index 6861754749..0000000000 --- a/config/seeker_agent.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Configuration for the Seeker Agent framework ---- -version: 0.+ -repository_root: path to website with index.yml -default_agent_name: $(ruby -e "require 'json' ; puts JSON.parse(ENV['VCAP_APPLICATION'])['application_name']") diff --git a/docs/framework-seeker-security-provider.md b/docs/framework-seeker-security-provider.md new file mode 100644 index 0000000000..d4af7dd408 --- /dev/null +++ b/docs/framework-seeker-security-provider.md @@ -0,0 +1,24 @@ +# Seeker Security Provider Framework +The Seeker Security Provider Framework causes an application to be bound with a [Seeker Security Provider][s] service instance. + + + + + + + + + +
Detection CriterionExistence of a single bound Seeker Security Provider service. The existence of a provider service is defined by the VCAP_SERVICES payload containing a service name, label or tag with seeker as a substring. +
Tagsseeker-service-provider
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +When binding Appinternals using a user-provided service, it must have seeker as substring. The credential payload must contain the following entries: + +| Name | Description +| ---- | ----------- +| `seeker_server_url` | The fully qualified URL of a Synopsys Seeker Server (e.g. `https://seeker.example.com`) + +**NOTE** +In order to use this integration, the Seeker Server version must be at least `2019.08` or later. diff --git a/lib/java_buildpack/framework/seeker_security_provider.rb b/lib/java_buildpack/framework/seeker_security_provider.rb index 5b395b9639..c45f5619ed 100644 --- a/lib/java_buildpack/framework/seeker_security_provider.rb +++ b/lib/java_buildpack/framework/seeker_security_provider.rb @@ -15,163 +15,78 @@ # See the License for the specific language governing permissions and # limitations under the License. -require 'java_buildpack/logging/logger_factory' require 'java_buildpack/component/base_component' require 'java_buildpack/framework' -require 'fileutils' -require 'net/http' -require 'json' -require 'date' -require 'cgi' +require 'java_buildpack/util/dash_case' module JavaBuildpack module Framework # Encapsulates the functionality for enabling zero-touch Seeker support. class SeekerSecurityProvider < JavaBuildpack::Component::BaseComponent + # Creates an instance # # @param [Hash] context a collection of utilities used the component def initialize(context) super(context) - @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger SeekerSecurityProvider + + @uri = download_url(credentials) if supports? end # (see JavaBuildpack::Component::BaseComponent#detect) def detect - @application.services.one_service? FILTER + @uri ? self.class.to_s.dash_case : nil end # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - @logger.info { 'Seeker buildpack compile stage start' } - credentials = fetch_credentials - @logger.info { "Credentials #{credentials}" } - assert_configuration_valid(credentials) - if should_download_sensor(credentials[ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY]) - fetch_agent_within_sensor(credentials) - else - fetch_agent_direct(credentials) + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, 'Downloading from Synopsys Seeker Server' + ) do + download_zip('', @uri, false, @droplet.sandbox, @component_name) end @droplet.copy_resources - end - - # extract seeker relevant configuration as map - def fetch_credentials - service = @application.services.find_service FILTER - service['credentials'] - end - - # verify required agent configuration is present - def assert_configuration_valid(credentials) - mandatory_config_keys = - [ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY, SENSOR_HOST_SERVICE_CONFIG_KEY, - SENSOR_PORT_SERVICE_CONFIG_KEY, SEEKER_SERVER_URL_CONFIG_KEY] - mandatory_config_keys.each do |config_key| - raise "'#{config_key}' credential must be set" unless credentials[config_key] - end + rescue StandardError => e + raise "Synopsys Seeker download failed: #{e}" end # (see JavaBuildpack::Component::BaseComponent#release) def release - @logger.info { 'Seeker buildpack release stage start' } - credentials = fetch_credentials + c = credentials + @droplet.java_opts.add_javaagent(@droplet.sandbox + 'seeker-agent.jar') @droplet.environment_variables - .add_environment_variable('SEEKER_SENSOR_HOST', credentials[SENSOR_HOST_SERVICE_CONFIG_KEY]) - .add_environment_variable('SEEKER_SENSOR_HTTP_PORT', credentials[SENSOR_PORT_SERVICE_CONFIG_KEY]) - .add_environment_variable('SEEKER_SERVER_URL', credentials[SEEKER_SERVER_URL_CONFIG_KEY]) + .add_environment_variable('SEEKER_SERVER_URL', c[SEEKER_SERVER_URL_CONFIG_KEY]) end - # JSON key for the host of the seeker sensor - SENSOR_HOST_SERVICE_CONFIG_KEY = 'sensor_host' - - # JSON key for the port of the seeker sensor - SENSOR_PORT_SERVICE_CONFIG_KEY = 'sensor_port' - # JSON key for the address of seeker sensor - SEEKER_SERVER_URL_CONFIG_KEY = 'seeker_server_url' - - # Enterprise server url, for example: `https://seeker-server.com:8082` - ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY = 'enterprise_server_url' - - # Relative path of the sensor zip - SENSOR_ZIP_RELATIVE_PATH_AT_ENTERPRISE_SERVER = 'rest/ui/installers/binaries/LINUX' - - # Relative path of the Java agent jars after Sensor extraction - AGENT_JARS_PATH = 'inline/agents/java/*' + private # Relative path of the agent zip AGENT_PATH = '/rest/api/latest/installers/agents/binaries/JAVA' - # Version details of Seekers server REST API path - SEEKER_VERSION_API = '/rest/api/version' - # seeker service name identifier - FILTER = /seeker/.freeze - - private_constant :SENSOR_HOST_SERVICE_CONFIG_KEY, :SENSOR_PORT_SERVICE_CONFIG_KEY, - :ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY, :SENSOR_ZIP_RELATIVE_PATH_AT_ENTERPRISE_SERVER, - :AGENT_JARS_PATH, :AGENT_PATH, :SEEKER_VERSION_API - - private - - def should_download_sensor(server_base_url) - json_response = get_seeker_version_details(server_base_url) - @logger.debug { "Seeker server response for version WS: #{json_response}" } - seeker_version_response = JSON.parse(json_response) - seeker_version = seeker_version_response['version'] - version_prefix = seeker_version[0, 7] - last_seeker_version_without_agent_direct_download_date = Date.parse('2018.05.01') - @logger.info { "Current Seeker version #{version_prefix}" } - current_seeker_version = Date.parse(version_prefix + '.01') - current_seeker_version <= last_seeker_version_without_agent_direct_download_date - end + FILTER = /seeker/i.freeze - def get_seeker_version_details(server_base_url) - uri = URI.parse(server_base_url) - http = Net::HTTP.new(uri.host, uri.port) - if uri.scheme == 'https' - http.verify_mode = OpenSSL::SSL::VERIFY_NONE - http.use_ssl = true - end - http_response = http.request_get(SEEKER_VERSION_API) - http_response.body - end + # JSON key for the address of seeker sensor + SEEKER_SERVER_URL_CONFIG_KEY = 'seeker_server_url' - def agent_direct_link(credentials) - URI.join(credentials[ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY], AGENT_PATH).to_s - end + private_constant :AGENT_PATH, :FILTER, :SEEKER_SERVER_URL_CONFIG_KEY - def fetch_agent_direct(credentials) - @logger.info { 'Trying to download agent directly...' } - java_agent_zip_uri = agent_direct_link(credentials) - download_agent(java_agent_zip_uri) + def credentials + @application.services.find_service(FILTER, SEEKER_SERVER_URL_CONFIG_KEY)['credentials'] end - def download_agent(java_agent_zip_uri) - @logger.debug { "Before downloading Agent from: #{java_agent_zip_uri}" } - download_zip('', java_agent_zip_uri, false, @droplet.sandbox) + def download_url(credentials) + "#{credentials[SEEKER_SERVER_URL_CONFIG_KEY]}#{AGENT_PATH}" end - def fetch_agent_within_sensor(credentials) - @logger.info { 'Trying to download sensor...' } - seeker_tmp_dir = @droplet.sandbox + 'seeker_tmp_sensor' - shell "rm -rf #{seeker_tmp_dir}" - sensor_direct_link = sensor_direct_link(credentials) - @logger.debug { "Before downloading Sensor from: #{sensor_direct_link}" } - download_zip('', sensor_direct_link, - false, seeker_tmp_dir, 'SensorInstaller.zip') - inner_jar_file = seeker_tmp_dir + 'SeekerInstaller.jar' - # Unzip only the java agent - to save time - shell "unzip -j #{inner_jar_file} #{AGENT_JARS_PATH} -d #{@droplet.sandbox} 2>&1" - shell "rm -rf #{seeker_tmp_dir}" + def supports? + @application.services.one_service?(FILTER, SEEKER_SERVER_URL_CONFIG_KEY) end - def sensor_direct_link(credentials) - enterprise_server_uri = URI.parse(credentials[ENTERPRISE_SERVER_URL_SERVICE_CONFIG_KEY].strip) - URI.join(enterprise_server_uri, SENSOR_ZIP_RELATIVE_PATH_AT_ENTERPRISE_SERVER).to_s - end end + end + end diff --git a/spec/fixtures/sensor.zip b/spec/fixtures/sensor.zip deleted file mode 100644 index 0e38bec5fcbfa666199169ea3b18f9746a42fe08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 762 zcmWIWW@Zs#-~hryY43d)pkOZx1A{Pw0z+_WYIbUoXI^nhVopwKkzQ6}QD_J+1N$CH z?`Rk9*0WO>2NzyKz=KcuBSOiFn0AR&Rf`te}~79Spg158Iw{@nTN3=d<0sZmDO zjYbP&eRX4fQP-Py0zy)2I8r-buB=o&swybn_n?&-di9j0fhCO~78!{L*#eLUkSzy!00x#co@Znr+B*T>tRUAjFahCqAg#*;;sF4c CpY>Y+ diff --git a/spec/fixtures/seeker-java-agent.zip b/spec/fixtures/stub-seeker-agent.zip similarity index 100% rename from spec/fixtures/seeker-java-agent.zip rename to spec/fixtures/stub-seeker-agent.zip diff --git a/spec/java_buildpack/framework/seeker_security_agent_spec.rb b/spec/java_buildpack/framework/seeker_security_agent_spec.rb index 71ee1a973a..9fc91f6bac 100644 --- a/spec/java_buildpack/framework/seeker_security_agent_spec.rb +++ b/spec/java_buildpack/framework/seeker_security_agent_spec.rb @@ -22,163 +22,40 @@ describe JavaBuildpack::Framework::SeekerSecurityProvider do include_context 'with component help' - let(:configuration) do - { 'some_property' => nil } - end - it 'does not detect without seeker service' do - expect(component.detect).to be_falsey + expect(component.detect).to be_nil end context do - let(:credentials) { {} } - before do - allow(services).to receive(:one_service?).with(/seeker/).and_return(true) - allow(services).to receive(:find_service).and_return('credentials' => credentials) - end + allow(services).to receive(:one_service?).with(/seeker/i, 'seeker_server_url').and_return(true) - it 'detects with seeker service' do - expect(component.detect).to be_truthy - end + allow(services).to receive(:find_service).and_return('credentials' => { 'seeker_server_url' => + 'http://localhost' }) - context do - let(:credentials) do - { 'sensor_port' => '9911', - 'sensor_host' => 'localhost' } - end - - it 'raises error if `enterprise_server_url` not specified' do - expect { component.compile }.to raise_error(/'enterprise_server_url' credential must be set/) - end + allow(application_cache).to receive(:get).with('http://localhost/rest/api/latest/installers/agents/binaries/JAVA') + .and_yield(Pathname.new('spec/fixtures/stub-seeker-agent.zip').open, + false) end - context do - let(:credentials) do - { 'sensor_port' => '9911', - 'sensor_host' => 'localhost', - 'enterprise_server_url' => 'some-url' } - end - - it 'raises error if `seeker_server_url` not specified' do - expect { component.compile }.to raise_error(/'seeker_server_url' credential must be set/) - end + it 'detects with seeker service' do + expect(component.detect).to eq('seeker-security-provider') end - context do - let(:credentials) do - { 'enterprise_server_url' => 'http://10.120.9.117:8082', - 'sensor_port' => '9911' } - end - - it 'raises error if `sensor_host` not specified' do - expect { component.compile }.to raise_error(/'sensor_host' credential must be set/) - end + it 'expands Seeker agent zip for agent direct download' do + component.compile + expect(sandbox + 'seeker-agent.jar').to exist end - context do - let(:credentials) do - { 'enterprise_server_url' => 'http://10.120.9.117:8082', - 'sensor_host' => 'localhost' } - end - - it 'raises error if `sensor_port` not specified' do - expect { component.compile }.to raise_error(/'sensor_port' credential must be set/) - end + it 'updates JAVA_OPTS' do + component.release + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/seeker_security_provider/seeker-agent.jar') + expect(environment_variables).to include('SEEKER_SERVER_URL=http://localhost') end - context do - let(:credentials) do - { 'enterprise_server_url' => 'http://10.120.9.117:8082', - 'seeker_server_url' => 'http://10.120.9.117:9911', - 'sensor_host' => 'localhost', - 'sensor_port' => '9911' } - end - - before do - allow(component).to receive(:agent_direct_link).with(credentials).and_return('test-uri') - end - - it 'expands Seeker agent zip for agent direct download', - cache_fixture: 'seeker-java-agent.zip' do - - allow(component).to receive(:should_download_sensor).and_return(false) - component.compile - - expect(sandbox + 'seeker-agent.jar').to exist - - end - it 'Chooses downloading the agent for Seeker versions newer than 2018.05', - cache_fixture: 'seeker-java-agent.zip' do - agent_download_expected_dates = ['2018.06', '2018.07', '2018.08', '2018.09', '2018.10', '2018.11', - '2018.12', '2019.01', '2019.02', '2019.03', '2019.04', '2019.05'] - agent_download_expected_dates.each do |seeker_version| - json_version_mock_response = - ["{\"publicName\":\"Seeker Enterprise Server\",\"version\":\"#{seeker_version}\"", - ',"buildNumber":"20121550","scmBranch":"origin/release/v2018.06","scmRevision":"809"}'].join(' ') - allow(component).to receive(:get_seeker_version_details) - .with(credentials['enterprise_server_url']).and_return(json_version_mock_response) - allow(component).to receive(:download_agent) - component.compile - end - - end - it 'updates JAVA_OPTS' do - component.release - - expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/seeker_security_provider/seeker-agent.jar') - end - - end - - context do - let(:credentials) do - { 'enterprise_server_url' => 'http://10.120.9.117:8082', - 'seeker_server_url' => 'http://10.120.9.117:9911', - 'sensor_host' => 'localhost', - 'sensor_port' => '9911' } - end - - before do - allow(component).to receive(:sensor_direct_link).with(credentials).and_return('test-uri') - end - - it 'expands Seeker agent from within sensor zip', - cache_fixture: 'sensor.zip' do - allow(component).to receive(:should_download_sensor).and_return(true) - component.compile - - expect(sandbox + 'seeker-agent.jar').to exist - - end - - it 'Chooses downloading the sensor for Seeker versions older than 2018.05 (including 2018.05)', - cache_fixture: 'sensor.zip' do - sensor_download_expected_dates = ['2018.05', '2018.04', '2018.03', '2018.02', '2018.01', '2017.12', '2017.11', - '2017.10', '2017.09', '2017.08', '2017.05', - '2017.04', '2017.03', '2017.02', '2017.01'] - sensor_download_expected_dates.each do |seeker_version| - json_version_mock_response = - ["{\"publicName\":\"Seeker Enterprise Server\",\"version\":\"#{seeker_version}\"", - ',"buildNumber":"20121550","scmBranch":"origin/release/v2018.06","scmRevision":"809"}'].join(' ') - allow(component).to receive(:get_seeker_version_details) - .with(credentials['enterprise_server_url']).and_return(json_version_mock_response) - allow(component).to receive(:fetch_agent_within_sensor).with(credentials) - component.compile - end - - end - - it 'updates JAVA_OPTS' do - component.release - - expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/seeker_security_provider/seeker-agent.jar') - end - - end end end From a43eaa71bff945ba22e8cbc965e2047157d5b1cf Mon Sep 17 00:00:00 2001 From: Harsh Patel Date: Mon, 21 Oct 2019 19:24:24 -0700 Subject: [PATCH 550/812] Downloadable Configuration If APPD_CONF_HTTP_URL is specified, download configuration files from that endpoint and map them to the corresponding agent directory. [#753] Signed-off-by: Ben Hale --- .../framework/app_dynamics_agent.rb | 67 ++++++++++++++++++- .../framework/app_dynamics_agent_spec.rb | 21 +++++- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index b681f8d3b6..0bf857b8ce 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -24,6 +24,19 @@ module Framework # Encapsulates the functionality for enabling zero-touch AppDynamics support. class AppDynamicsAgent < JavaBuildpack::Component::VersionedDependencyComponent + @conf_files = [ + 'logging/log4j2.xml', + 'logging/log4j.xml', + 'app-agent-config.xml', + 'controller-info.xml', + 'service-endpoint.xml', + 'transactions.xml' + ] + + def initialize(context) + super(context) + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger AppDynamicsAgent + end # (see JavaBuildpack::Component::BaseComponent#compile) def compile @@ -34,7 +47,7 @@ def compile default_conf_dir = resources_dir + @droplet.component_id + 'defaults' copy_appd_default_configuration(default_conf_dir) - + override_default_config_if_applicable @droplet.copy_resources end @@ -129,7 +142,57 @@ def copy_appd_default_configuration(default_conf_dir) end end - end + # Check if configuration file exists on the server before download + # @param [ResourceURI] uri URI of the remote configuration server + # @param [ConfigFileName] conf_file Name of the configuration file + # @return [Boolean] returns true if files exists on path specified by APPD_CONF_HTTP_URL, false otherwise + def check_if_resource_exists(resource_uri, conf_file) + # check if resource exists on remote server + begin + response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http| + http.request_head(resource_uri) + end + rescue StandardError => e + @logger.error { "Request failure: #{e.message}" } + return false + end + case response + when Net::HTTPSuccess + return true + when Net::HTTPRedirection + location = response['location'] + @logger.info { "redirected to #{location}" } + return check_if_resource_exists(location, conf_file) + else + @logger.info { "Could not retrieve #{resource_uri}. Code: #{response.code} Message: #{response.message}" } + return false + end + end + + # Check for configuration files on a remote server. If found, copy to conf dir under each ver* dir + # @return [Void] + def override_default_config_if_applicable + return unless @application.environment['APPD_CONF_HTTP_URL'] + + agent_root = @application.environment['APPD_CONF_HTTP_URL'].chomp('/') + '/java/' + @logger.info { "Downloading override configuration files from #{agent_root}" } + JavaBuildpack::Framework::AppDynamicsAgent.instance_variable_get(:@conf_files).each do |conf_file| + uri = URI(agent_root + conf_file) + + # `download()` uses retries with exponential backoff which is expensive + # for situations like 404 File not Found. Also, `download()` doesn't expose + # an api to disable retries, which makes this check necessary to prevent + # long install times. + next unless check_if_resource_exists(uri, conf_file) + + download(false, uri.to_s) do |file| + Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| + FileUtils.cp_r file, target_directory + '/conf/' + conf_file + end + end + end + end + end end end diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 02268f55ad..b91556f9c6 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -141,8 +141,25 @@ expect(java_opts).to include('-Dappdynamics.agent.accountAccessKey=test-account-access-key') end end - end - end + context do + let(:environment) { { 'APPD_CONF_HTTP_URL' => 'http://foo.com' } } + let(:conf_files) { described_class.instance_variable_get(:@conf_files) } + + it 'sets APPD_CONF_HTTP_URL env var to download config files from', + cache_fixture: 'stub-app-dynamics-agent.zip' do + conf_files.each do |file| + uri = "http://foo.com/java/#{file}" + allow(application_cache).to receive(:get) + .with(uri) + stub_request(:head, uri) + .with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby' }) + .to_return(status: 200, body: '', headers: {}) + end + component.compile + end + end + end + end end From f4cac2144102f5e141281d90bda7d0898d111f4f Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 8 Nov 2019 11:08:08 -0800 Subject: [PATCH 551/812] Polishing [resolves #753] Signed-off-by: Ben Hale --- .../framework/app_dynamics_agent.rb | 19 +++++++------------ .../framework/app_dynamics_agent_spec.rb | 6 +++++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 0bf857b8ce..1e00c4312c 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -24,14 +24,6 @@ module Framework # Encapsulates the functionality for enabling zero-touch AppDynamics support. class AppDynamicsAgent < JavaBuildpack::Component::VersionedDependencyComponent - @conf_files = [ - 'logging/log4j2.xml', - 'logging/log4j.xml', - 'app-agent-config.xml', - 'controller-info.xml', - 'service-endpoint.xml', - 'transactions.xml' - ] def initialize(context) super(context) @@ -43,7 +35,7 @@ def compile download_zip(false, @droplet.sandbox, 'AppDynamics Agent') # acessor for resources dir through @droplet? - resources_dir = Pathname.new(File.expand_path('../../../resources', __dir__)).freeze + resources_dir = Pathname.new(File.expand_path('../../../resources', __dir__)).freeze default_conf_dir = resources_dir + @droplet.component_id + 'defaults' copy_appd_default_configuration(default_conf_dir) @@ -54,7 +46,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release credentials = @application.services.find_service(FILTER, 'host-name')['credentials'] - java_opts = @droplet.java_opts + java_opts = @droplet.java_opts java_opts.add_javaagent(@droplet.sandbox + 'javaagent.jar') application_name java_opts, credentials @@ -77,9 +69,12 @@ def supports? private + CONFIG_FILES = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml + service-endpoint.xml transactions.xml].freeze + FILTER = /app[-]?dynamics/.freeze - private_constant :FILTER + private_constant :CONFIG_FILES, :FILTER def application_name(java_opts, credentials) name = credentials['application-name'] || @configuration['default_application_name'] || @@ -177,7 +172,7 @@ def override_default_config_if_applicable agent_root = @application.environment['APPD_CONF_HTTP_URL'].chomp('/') + '/java/' @logger.info { "Downloading override configuration files from #{agent_root}" } - JavaBuildpack::Framework::AppDynamicsAgent.instance_variable_get(:@conf_files).each do |conf_file| + CONFIG_FILES.each do |conf_file| uri = URI(agent_root + conf_file) # `download()` uses retries with exponential backoff which is expensive diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index b91556f9c6..051a996106 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -149,7 +149,11 @@ it 'sets APPD_CONF_HTTP_URL env var to download config files from', cache_fixture: 'stub-app-dynamics-agent.zip' do - conf_files.each do |file| + + config_files = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml + service-endpoint.xml transactions.xml] + + config_files.each do |file| uri = "http://foo.com/java/#{file}" allow(application_cache).to receive(:get) .with(uri) From ff5c4c5756d59d15d5f7abd6c4d248ee72d820c7 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Fri, 3 Jan 2020 11:21:37 -0800 Subject: [PATCH 552/812] Remove Dynatrace OneAgent Download Previously, the Dynatrace OneAgent agent had to be downloaded from the Internet. More recently, this agent is downloaded from the OneAgent server directly, and it no longer must be packaged within the buildpack. This change removes the configuration that caused it to be downloaded. [resolves #764] Signed-off-by: Ben Hale --- config/dynatrace_one_agent.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 config/dynatrace_one_agent.yml diff --git a/config/dynatrace_one_agent.yml b/config/dynatrace_one_agent.yml deleted file mode 100644 index e10e2c6535..0000000000 --- a/config/dynatrace_one_agent.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Configuration for the Dynatrace SaaS/Managed framework ---- -version: 1.+ -repository_root: https://download.ruxit.com/agent/paas/cloudfoundry/java From 8d9975f10d4f36bed10da97f57c8efa9dafe0f3b Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Mon, 6 Jan 2020 10:06:13 -0800 Subject: [PATCH 553/812] Bypass VersionedDependencyComponent's resolution In a previous commit for this change, a bug was introduced where the VersionedDependencyComponent's resolution was still performed, even though there was no where to look for dependencies any longer. This change fixes that bug by ensuring that the VersionedDependencyComponent's resolution is bypassed. [#764] Signed-off-by: Ben Hale --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 1cce938d93..cb1785484d 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -32,7 +32,11 @@ class DynatraceOneAgent < JavaBuildpack::Component::VersionedDependencyComponent # # @param [Hash] context a collection of utilities used the component def initialize(context) - super(context) + @application = context[:application] + @component_name = self.class.to_s.space_case + @configuration = context[:configuration] + @droplet = context[:droplet] + @version, @uri = agent_download_url if supports? @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger DynatraceOneAgent end From 3ebda04a5830f5956bbe64334a6e66095f90b25f Mon Sep 17 00:00:00 2001 From: Stefan Mayr Date: Sun, 19 Jan 2020 14:24:16 +0100 Subject: [PATCH 554/812] Documentation Polishing This change fixes a rogue line break in the Oracle JRE `cf set-env` example, and unifies the documentation for all JREs. [resolves #769] Signed-off-by: Ben Hale --- docs/jre-ibm_jre.md | 9 +++++---- docs/jre-oracle_jre.md | 11 ++++++----- docs/jre-sap_machine_jre.md | 9 +++++---- docs/jre-zulu_jre.md | 9 +++++---- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/docs/jre-ibm_jre.md b/docs/jre-ibm_jre.md index 8660c4b9b8..a4fbe44706 100644 --- a/docs/jre-ibm_jre.md +++ b/docs/jre-ibm_jre.md @@ -11,11 +11,12 @@ For general information on configuring the buildpack, including how to specify c The JRE can be configured by modifying the [`config/ibm_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so, it supports the [version syntax][] defined there. -To use IBM JRE instead of OpenJDK without forking java-buildpack, set environment variable: +To use IBM JRE instead of OpenJDK without forking java-buildpack, set environment variable and restage: -`cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::IbmJRE"]}'` - -`cf restage ` +```bash +cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::IbmJRE"]}' +cf restage +``` | Name | Description | ---- | ----------- diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 012a278465..48d1091ae5 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -31,12 +31,13 @@ For general information on configuring the buildpack, including how to specify c The JRE can be configured by modifying the [`config/oracle_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. -To use Oracle JRE instead of OpenJDK without forking java-buildpack, set environment variable: +To use Oracle JRE instead of OpenJDK without forking java-buildpack, set environment variable and restage: -`cf set-env JBP_CONFIG_COMPONENTS '{ jres: [ "JavaBuildpack::Jre::OracleJRE" ] }'` -`cf set-env JBP_CONFIG_ORACLE_JRE '{ jre: { repository_root: "" } }'` - -`cf restage ` +```bash +cf set-env JBP_CONFIG_COMPONENTS '{ jres: [ "JavaBuildpack::Jre::OracleJRE" ] }' +cf set-env JBP_CONFIG_ORACLE_JRE '{ jre: { repository_root: "" } }' +cf restage +``` | Name | Description | ---- | ----------- diff --git a/docs/jre-sap_machine_jre.md b/docs/jre-sap_machine_jre.md index b91c9c4827..28057bb20d 100644 --- a/docs/jre-sap_machine_jre.md +++ b/docs/jre-sap_machine_jre.md @@ -22,11 +22,12 @@ For general information on configuring the buildpack, including how to specify c The JRE can be configured by modifying the [`config/sap_machine_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. -To use SapMachine JRE instead of OpenJDK without forking java-buildpack, set environment variable: +To use SapMachine JRE instead of OpenJDK without forking java-buildpack, set environment variable and restage: -`cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::SapMachineJRE"]}'` - -`cf restage ` +```bash +cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::SapMachineJRE"]}' +cf restage +``` | Name | Description | ---- | ----------- diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index 3952679f6a..cc70bec43b 100644 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -23,11 +23,12 @@ For general information on configuring the buildpack, including how to specify c The JRE can be configured by modifying the [`config/zulu_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so, it supports the [version syntax][] defined there. -To use Zulu JRE instead of OpenJDK without forking java-buildpack, set environment variable: +To use Zulu JRE instead of OpenJDK without forking java-buildpack, set environment variable and restage: -`cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::ZuluJRE"]}'` - -`cf restage ` +```bash +cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::ZuluJRE"]}' +cf restage +``` | Name | Description | ---- | ----------- From ecbf660ce1426583283b223670ec7731c7986f34 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 4 Feb 2020 08:43:49 -0800 Subject: [PATCH 555/812] Polishing Signed-off-by: Ben Hale --- .idea/runConfigurations/All_Tests__2_4_.xml | 2 +- .idea/runConfigurations/All_Tests__2_5_.xml | 2 +- .idea/runConfigurations/All_Tests__2_6_.xml | 2 +- .idea/runConfigurations/Without_Integration_Tests__2_4_.xml | 2 +- .idea/runConfigurations/Without_Integration_Tests__2_5_.xml | 2 +- .idea/runConfigurations/Without_Integration_Tests__2_6_.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.idea/runConfigurations/All_Tests__2_4_.xml b/.idea/runConfigurations/All_Tests__2_4_.xml index 5bb204b942..58801955c8 100644 --- a/.idea/runConfigurations/All_Tests__2_4_.xml +++ b/.idea/runConfigurations/All_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_5_.xml b/.idea/runConfigurations/All_Tests__2_5_.xml index 80804e6bef..23c1e9c961 100644 --- a/.idea/runConfigurations/All_Tests__2_5_.xml +++ b/.idea/runConfigurations/All_Tests__2_5_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_6_.xml b/.idea/runConfigurations/All_Tests__2_6_.xml index 9ca5516534..12e3ffda45 100644 --- a/.idea/runConfigurations/All_Tests__2_6_.xml +++ b/.idea/runConfigurations/All_Tests__2_6_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml index e4c446beb6..db1d38de8e 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_4_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml index 0d4b4df2bf..b15659cab9 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml @@ -5,7 +5,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml index 3a184a6142..e6b8986c28 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml @@ -5,7 +5,7 @@ - + From 13834f4de622eea82d45052193946e4f77b65f12 Mon Sep 17 00:00:00 2001 From: Stefan Mayr Date: Sat, 18 Jan 2020 23:57:26 +0100 Subject: [PATCH 556/812] GraalVM JRE This change adds support for GraalVM as another JRE option. [#755][#768] Signed-off-by: Ben Hale --- README.md | 1 + config/components.yml | 1 + config/graal_vm_jre.yml | 31 +++++ docs/jre-graal_vm_jre.md | 178 +++++++++++++++++++++++++ lib/java_buildpack/jre/graal_vm_jre.rb | 30 +++++ 5 files changed, 241 insertions(+) create mode 100644 config/graal_vm_jre.yml create mode 100644 docs/jre-graal_vm_jre.md create mode 100644 lib/java_buildpack/jre/graal_vm_jre.rb diff --git a/README.md b/README.md index 2f7045e0cd..d5a84c3391 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ The buildpack supports extension through the use of Git repository forking. The * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) * Standard JREs * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) + * [GraalVM](docs/jre-graal_vm_jre.md) ([Configuration](docs/jre-graal_vm_jre.md#configuration)) * [IBM® SDK, Java™ Technology Edition](docs/jre-ibm_jre.md) ([Configuration](docs/jre-ibm_jre.md#configuration)) * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) * [Oracle](docs/jre-oracle_jre.md) ([Configuration](docs/jre-oracle_jre.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 2221f6fec9..8e1f4e69f0 100644 --- a/config/components.yml +++ b/config/components.yml @@ -34,6 +34,7 @@ jres: # - "JavaBuildpack::Jre::OracleJRE" # - "JavaBuildpack::Jre::ZuluJRE" # - "JavaBuildpack::Jre::SapMachineJRE" +# - "JavaBuildpack::Jre::GraalVmJRE" # Frameworks are processed in order. # The MultiBuildpack framework is first in order to allow any framework to override contributions from earlier buildpacks diff --git a/config/graal_vm_jre.yml b/config/graal_vm_jre.yml new file mode 100644 index 0000000000..68c5a14904 --- /dev/null +++ b/config/graal_vm_jre.yml @@ -0,0 +1,31 @@ +# Cloud Foundry Java Buildpack +# Copyright 2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# You must specify a the repository root of an GraalVM repository. Please see the documentation for more detail. +# e.g. repository_root: "https://example.com/graalvm-jre/{platform}/{architecture}" +--- +jre: + version: 19.3.+ + repository_root: "" +jvmkill_agent: + version: 1.+ + repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" +memory_calculator: + version: 3.+ + repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + class_count: + headroom: + stack_threads: 250 diff --git a/docs/jre-graal_vm_jre.md b/docs/jre-graal_vm_jre.md new file mode 100644 index 0000000000..c80ef30372 --- /dev/null +++ b/docs/jre-graal_vm_jre.md @@ -0,0 +1,178 @@ +# GraalVM JRE +The GraalVM JRE provides Java runtimes from [GraalVM][] project. No versions of the JRE are available be default due to licensing restrictions. Instead you will need to create a repository with the GraalVM JREs in it and configure the buildpack to use that repository. Unless otherwise configured, the version of Java that will be used is specified in [`config/graal_vm_jre.yml`][]. + + + + + + + + + + +
Detection CriterionUnconditional. Existence of a single bound Volume Service will result in Terminal heap dumps being written. +
    +
  • Existence of a Volume Service service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has heap-dump as a substring.
  • +
+
Tagsopen-jdk-like-jre=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩, jvmkill=⟨version⟩
+Tags are printed to standard output by the buildpack detect script + +**NOTE:** Unlike the [OpenJDK JRE][], this JRE does not connect to a pre-populated repository. Instead you will need to create your own repository by: + +1. Downloading the GraalVM JRE binary (in TAR format) to an HTTP-accesible location +1. Uploading an `index.yml` file with a mapping from the version of the JRE to its location to the same HTTP-accessible location +1. Configuring the [`config/graal_vm_jre.yml`][] file to point to the root of the repository holding both the index and JRE binary +1. Configuring the [`config/components.yml`][] file to disable the OpenJDK JRE and enable the GraalVM JRE + +For details on the repository structure, see the [repository documentation][repositories]. + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The JRE can be configured by modifying the [`config/graal_vm_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +To use GraalVM JRE instead of OpenJDK without forking java-buildpack, set environment variable and restage: + +```bash +cf set-env JBP_CONFIG_COMPONENTS '{ jres: [ "JavaBuildpack::Jre::GraalVmJRE" ] }' +cf set-env JBP_CONFIG_GRAAL_VM_JRE '{ jre: { repository_root: "" } }' +cf restage +``` + +| Name | Description +| ---- | ----------- +| `jre.repository_root` | The URL of the GraalVM repository index ([details][repositories]). +| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. +| `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. +| `memory_calculator` | Memory calculator defaults, described below under "Memory". + +### Additional Resources +The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/graal_vm_jre` directory in the buildpack fork. + +#### Custom CA Certificates +To add custom SSL certificates, add your `cacerts` file to `resources/graal_vm_jre/lib/security/cacerts`. This file will be overlayed onto the GraalVM distribution. + +### `jvmkill` +The `jvmkill` agent runs when an application has experience a resource exhaustion event. When this event occurs, the agent will print out a histogram of the first 100 largest types by total number of bytes. + +```plain +Resource exhaustion event: the JVM was unable to allocate memory from the heap. +ResourceExhausted! (1/0) +| Instance Count | Total Bytes | Class Name | +| 18273 | 313157136 | [B | +| 47806 | 7648568 | [C | +| 14635 | 1287880 | Ljava/lang/reflect/Method; | +| 46590 | 1118160 | Ljava/lang/String; | +| 8413 | 938504 | Ljava/lang/Class; | +| 28573 | 914336 | Ljava/util/concurrent/ConcurrentHashMap$Node; | +``` + +It will also print out a summary of all of the memory spaces in the JVM. + +```plain +Memory usage: + Heap memory: init 65011712, used 332392888, committed 351797248, max 351797248 + Non-heap memory: init 2555904, used 63098592, committed 64815104, max 377790464 +Memory pool usage: + Code Cache: init 2555904, used 14702208, committed 15007744, max 251658240 + PS Eden Space: init 16252928, used 84934656, committed 84934656, max 84934656 + PS Survivor Space: init 2621440, used 0, committed 19398656, max 19398656 + Compressed Class Space: init 0, used 5249512, committed 5505024, max 19214336 + Metaspace: init 0, used 43150616, committed 44302336, max 106917888 + PS Old Gen: init 43515904, used 247459792, committed 247463936, max 247463936 +``` + +If a [Volume Service][] with the string `heap-dump` in its name or tag is bound to the application, terminal heap dumps will be written with the pattern `/-/-/--.hprof` + +```plain +Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof +``` + +### Memory +The total available memory for the application's container is specified when an application is pushed. +The Java buildpack uses this value to control the JRE's use of various +regions of memory and logs the JRE memory settings when the application starts or restarts. +These settings can be influenced by configuring +the `stack_threads` and/or `class_count` mappings (both part of the `memory_calculator` mapping), +and/or Java options relating to memory. + +Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. + +#### Total Memory + +The user can change the container's total memory available to influence the JRE memory settings. +Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory +available results in the heap size setting increasing or decreasing by a corresponding amount. + +#### Loaded Classes + +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: + +```yaml +class_count: 500 +``` + +#### Headroom + +A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. + +```yaml +headroom: 10 +``` + +#### Stack Threads + +The amount of memory that should be allocated to stacks is given as an amount of memory per thread with the Java option `-Xss`. If an explicit number of threads should be used for the calculation of stack memory, then it should be specified as in the following example: + +```yaml +stack_threads: 500 +``` + +Note that the default value of 250 threads is optimized for a default Tomcat configuration. If you are using another container, especially something non-blocking like Netty, it's more appropriate to use a significantly smaller value. Typically 25 threads would cover the needs of both the server (Netty) and the threads started by the JVM itself. + +#### Java Options + +If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to +specific values. The heap size can be set explicitly, but changing the value of options other +than the heap size can also affect the heap size. For example, if the user increases +the maximum direct memory size from its default value of 10 Mb to 20 Mb, then this will +reduce the calculated heap size by 10 Mb. + +#### Memory Calculation +Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. + +The container's total available memory is allocated into heap, metaspace and compressed class space (or permanent generation for Java 7), +direct memory, and stack memory settings. + +The memory calculation is described in more detail in the [Memory Calculator's README]. + +The inputs to the memory calculation, except the container's total memory (which is unknown at staging time), are logged during staging, for example: +``` +Loaded Classes: 13974, Threads: 300, JAVA_OPTS: '' +``` + +The container's total memory is logged during `cf push` and `cf scale`, for example: +``` + state since cpu memory disk details +#0 running 2017-04-10 02:20:03 PM 0.0% 896K of 1G 1.3M of 1G +``` + +The JRE memory settings are logged when the application is started or re-started, for example: +``` +JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199K \ + -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=18134K -Xss1M -Xmx368042K +``` + +[`config/components.yml`]: ../config/components.yml +[`config/graal_vm_jre.yml`]: ../config/graal_vm_jre.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml +[Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[OpenJDK JRE]: jre-open_jdk_jre.md +[GraalVM]: https://www.graalvm.org/ +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering +[Volume Service]: https://docs.cloudfoundry.org/devguide/services/using-vol-services.html diff --git a/lib/java_buildpack/jre/graal_vm_jre.rb b/lib/java_buildpack/jre/graal_vm_jre.rb new file mode 100644 index 0000000000..debaccb0eb --- /dev/null +++ b/lib/java_buildpack/jre/graal_vm_jre.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2018 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/jre' +require 'java_buildpack/jre/open_jdk_like' + +module JavaBuildpack + module Jre + + # Encapsulates the detect, compile, and release functionality for selecting an GraalVM JRE. + class GraalVmJRE < OpenJDKLike + end + + end +end From c807a36e9a976df6a3c396dae6a688f59e64f400 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 4 Feb 2020 15:34:31 -0800 Subject: [PATCH 557/812] Polishing [resolves #755][resolves #768] Signed-off-by: Ben Hale --- config/components.yml | 2 +- config/graal_vm_jre.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/components.yml b/config/components.yml index 8e1f4e69f0..72d10418a7 100644 --- a/config/components.yml +++ b/config/components.yml @@ -29,12 +29,12 @@ containers: # Example: cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::OpenJdkJRE"]}' # Please see the documentation for more detail. jres: +# - "JavaBuildpack::Jre::GraalVmJRE" # - "JavaBuildpack::Jre::IbmJRE" - "JavaBuildpack::Jre::OpenJdkJRE" # - "JavaBuildpack::Jre::OracleJRE" # - "JavaBuildpack::Jre::ZuluJRE" # - "JavaBuildpack::Jre::SapMachineJRE" -# - "JavaBuildpack::Jre::GraalVmJRE" # Frameworks are processed in order. # The MultiBuildpack framework is first in order to allow any framework to override contributions from earlier buildpacks diff --git a/config/graal_vm_jre.yml b/config/graal_vm_jre.yml index 68c5a14904..b36d34f9b8 100644 --- a/config/graal_vm_jre.yml +++ b/config/graal_vm_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2018 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 42e6a5bf895679e164a5c6028d7caa4bfbcbb9e3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 4 Feb 2020 16:01:04 -0800 Subject: [PATCH 558/812] Copyright Updates Signed-off-by: Ben Hale --- .idea/copyright/Apache_License__Version_2_0.xml | 5 +---- CONTRIBUTING.md | 6 +++--- Rakefile | 2 +- bin/compile | 2 +- bin/detect | 2 +- bin/finalize | 2 +- bin/release | 2 +- ci/auto-merge.sh | 2 +- ci/auto-merge.yml | 2 +- ci/package-test.sh | 2 +- ci/package-test.yml | 2 +- ci/unit-test.sh | 2 +- ci/unit-test.yml | 2 +- ci/versions-json.sh | 2 +- ci/versions-json.yml | 2 +- ci/versions-markdown.sh | 2 +- ci/versions-markdown.yml | 2 +- ci/versions-yaml.sh | 2 +- ci/versions-yaml.yml | 2 +- ci/versions.sh | 2 +- ci/versions.yml | 2 +- config/app_dynamics_agent.yml | 2 +- config/aspectj_weaver_agent.yml | 2 +- config/azure_application_insights_agent.yml | 2 +- config/cache.yml | 2 +- config/client_certificate_mapper.yml | 2 +- config/components.yml | 2 +- config/container_customizer.yml | 2 +- config/container_security_provider.yml | 2 +- config/contrast_security_agent.yml | 2 +- config/debug.yml | 2 +- config/dynatrace_appmon_agent.yml | 2 +- config/elastic_apm_agent.yml | 2 +- config/google_stackdriver_debugger.yml | 2 +- config/google_stackdriver_profiler.yml | 2 +- config/groovy.yml | 2 +- config/ibm_jre.yml | 2 +- config/introscope_agent.yml | 2 +- config/jacoco_agent.yml | 2 +- config/java_main.yml | 2 +- config/java_memory_assistant.yml | 2 +- config/java_opts.yml | 2 +- config/jmx.yml | 2 +- config/jprofiler_profiler.yml | 2 +- config/jrebel_agent.yml | 2 +- config/logging.yml | 2 +- config/luna_security_provider.yml | 2 +- config/maria_db_jdbc.yml | 2 +- config/metric_writer.yml | 2 +- config/new_relic_agent.yml | 2 +- config/open_jdk_jre.yml | 2 +- config/oracle_jre.yml | 2 +- config/postgresql_jdbc.yml | 2 +- config/protect_app_security_provider.yml | 2 +- config/repository.yml | 2 +- config/riverbed_appinternals_agent.yml | 2 +- config/sap_machine_jre.yml | 2 +- config/sky_walking_agent.yml | 2 +- config/spring_auto_reconfiguration.yml | 2 +- config/spring_boot_cli.yml | 2 +- config/takipi_agent.yml | 2 +- config/tomcat.yml | 2 +- config/your_kit_profiler.yml | 2 +- config/zulu_jre.yml | 2 +- lib/java_buildpack.rb | 2 +- lib/java_buildpack/buildpack.rb | 2 +- lib/java_buildpack/buildpack_version.rb | 2 +- lib/java_buildpack/component.rb | 2 +- lib/java_buildpack/component/additional_libraries.rb | 2 +- lib/java_buildpack/component/application.rb | 2 +- lib/java_buildpack/component/base_component.rb | 2 +- lib/java_buildpack/component/droplet.rb | 2 +- lib/java_buildpack/component/environment_variables.rb | 2 +- lib/java_buildpack/component/extension_directories.rb | 2 +- lib/java_buildpack/component/immutable_java_home.rb | 2 +- lib/java_buildpack/component/java_opts.rb | 2 +- lib/java_buildpack/component/modular_component.rb | 2 +- lib/java_buildpack/component/mutable_java_home.rb | 2 +- lib/java_buildpack/component/networking.rb | 2 +- lib/java_buildpack/component/root_libraries.rb | 2 +- lib/java_buildpack/component/security_providers.rb | 2 +- lib/java_buildpack/component/services.rb | 2 +- .../component/versioned_dependency_component.rb | 2 +- lib/java_buildpack/container.rb | 2 +- lib/java_buildpack/container/dist_zip.rb | 2 +- lib/java_buildpack/container/dist_zip_like.rb | 2 +- lib/java_buildpack/container/groovy.rb | 2 +- lib/java_buildpack/container/java_main.rb | 2 +- lib/java_buildpack/container/play_framework.rb | 2 +- lib/java_buildpack/container/ratpack.rb | 2 +- lib/java_buildpack/container/spring_boot.rb | 2 +- lib/java_buildpack/container/spring_boot_cli.rb | 2 +- lib/java_buildpack/container/tomcat.rb | 2 +- .../container/tomcat/tomcat_access_logging_support.rb | 2 +- .../container/tomcat/tomcat_external_configuration.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_geode_store.rb | 2 +- .../container/tomcat/tomcat_insight_support.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_instance.rb | 2 +- .../container/tomcat/tomcat_lifecycle_support.rb | 2 +- .../container/tomcat/tomcat_logging_support.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_redis_store.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_setenv.rb | 2 +- lib/java_buildpack/container/tomcat/tomcat_utils.rb | 2 +- lib/java_buildpack/framework.rb | 2 +- lib/java_buildpack/framework/app_dynamics_agent.rb | 2 +- lib/java_buildpack/framework/aspectj_weaver_agent.rb | 2 +- .../framework/azure_application_insights_agent.rb | 2 +- lib/java_buildpack/framework/client_certificate_mapper.rb | 2 +- lib/java_buildpack/framework/container_customizer.rb | 2 +- lib/java_buildpack/framework/container_security_provider.rb | 2 +- lib/java_buildpack/framework/contrast_security_agent.rb | 2 +- lib/java_buildpack/framework/debug.rb | 2 +- lib/java_buildpack/framework/dynatrace_appmon_agent.rb | 2 +- lib/java_buildpack/framework/dynatrace_one_agent.rb | 2 +- lib/java_buildpack/framework/elastic_apm_agent.rb | 2 +- lib/java_buildpack/framework/google_stackdriver_debugger.rb | 2 +- lib/java_buildpack/framework/google_stackdriver_profiler.rb | 2 +- lib/java_buildpack/framework/introscope_agent.rb | 2 +- lib/java_buildpack/framework/jacoco_agent.rb | 2 +- lib/java_buildpack/framework/java_memory_assistant.rb | 2 +- lib/java_buildpack/framework/java_memory_assistant/agent.rb | 2 +- .../framework/java_memory_assistant/clean_up.rb | 2 +- .../framework/java_memory_assistant/heap_dump_folder.rb | 2 +- lib/java_buildpack/framework/java_opts.rb | 2 +- lib/java_buildpack/framework/java_security.rb | 2 +- lib/java_buildpack/framework/jmx.rb | 2 +- lib/java_buildpack/framework/jprofiler_profiler.rb | 2 +- lib/java_buildpack/framework/jrebel_agent.rb | 2 +- lib/java_buildpack/framework/luna_security_provider.rb | 2 +- lib/java_buildpack/framework/maria_db_jdbc.rb | 2 +- lib/java_buildpack/framework/metric_writer.rb | 2 +- lib/java_buildpack/framework/multi_buildpack.rb | 2 +- lib/java_buildpack/framework/new_relic_agent.rb | 2 +- lib/java_buildpack/framework/postgresql_jdbc.rb | 2 +- .../framework/protect_app_security_provider.rb | 2 +- lib/java_buildpack/framework/riverbed_appinternals_agent.rb | 2 +- lib/java_buildpack/framework/seeker_security_provider.rb | 2 +- lib/java_buildpack/framework/sky_walking_agent.rb | 2 +- lib/java_buildpack/framework/spring_auto_reconfiguration.rb | 2 +- lib/java_buildpack/framework/spring_insight.rb | 2 +- lib/java_buildpack/framework/takipi_agent.rb | 2 +- lib/java_buildpack/framework/your_kit_profiler.rb | 2 +- lib/java_buildpack/jre.rb | 2 +- lib/java_buildpack/jre/graal_vm_jre.rb | 2 +- lib/java_buildpack/jre/ibm_jre.rb | 2 +- lib/java_buildpack/jre/ibm_jre_initializer.rb | 2 +- lib/java_buildpack/jre/jvmkill_agent.rb | 2 +- lib/java_buildpack/jre/open_jdk_jre.rb | 2 +- lib/java_buildpack/jre/open_jdk_like.rb | 2 +- lib/java_buildpack/jre/open_jdk_like_jre.rb | 2 +- lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb | 2 +- lib/java_buildpack/jre/open_jdk_like_security_providers.rb | 2 +- lib/java_buildpack/jre/oracle_jre.rb | 2 +- lib/java_buildpack/jre/sap_machine_jre.rb | 2 +- lib/java_buildpack/jre/zulu_jre.rb | 2 +- lib/java_buildpack/logging.rb | 2 +- lib/java_buildpack/logging/delegating_logger.rb | 2 +- lib/java_buildpack/logging/logger_factory.rb | 2 +- lib/java_buildpack/repository.rb | 2 +- lib/java_buildpack/repository/configured_item.rb | 2 +- lib/java_buildpack/repository/repository_index.rb | 2 +- lib/java_buildpack/repository/version_resolver.rb | 2 +- lib/java_buildpack/util.rb | 2 +- lib/java_buildpack/util/cache.rb | 2 +- lib/java_buildpack/util/cache/application_cache.rb | 2 +- lib/java_buildpack/util/cache/cache_factory.rb | 2 +- lib/java_buildpack/util/cache/cached_file.rb | 2 +- lib/java_buildpack/util/cache/download_cache.rb | 2 +- lib/java_buildpack/util/cache/inferred_network_failure.rb | 2 +- lib/java_buildpack/util/cache/internet_availability.rb | 2 +- lib/java_buildpack/util/class_file_utils.rb | 2 +- lib/java_buildpack/util/colorize.rb | 2 +- lib/java_buildpack/util/configuration_utils.rb | 2 +- lib/java_buildpack/util/constantize.rb | 2 +- lib/java_buildpack/util/dash_case.rb | 2 +- lib/java_buildpack/util/file_enumerable.rb | 2 +- lib/java_buildpack/util/filtering_pathname.rb | 2 +- lib/java_buildpack/util/find_single_directory.rb | 2 +- lib/java_buildpack/util/format_duration.rb | 2 +- lib/java_buildpack/util/groovy_utils.rb | 2 +- lib/java_buildpack/util/jar_finder.rb | 2 +- lib/java_buildpack/util/java_main_utils.rb | 2 +- lib/java_buildpack/util/play.rb | 2 +- lib/java_buildpack/util/play/base.rb | 2 +- lib/java_buildpack/util/play/factory.rb | 2 +- lib/java_buildpack/util/play/post22.rb | 2 +- lib/java_buildpack/util/play/post22_dist.rb | 2 +- lib/java_buildpack/util/play/post22_staged.rb | 2 +- lib/java_buildpack/util/play/pre22.rb | 2 +- lib/java_buildpack/util/play/pre22_dist.rb | 2 +- lib/java_buildpack/util/play/pre22_staged.rb | 2 +- lib/java_buildpack/util/properties.rb | 2 +- lib/java_buildpack/util/qualify_path.rb | 2 +- lib/java_buildpack/util/ratpack_utils.rb | 2 +- lib/java_buildpack/util/sanitizer.rb | 2 +- lib/java_buildpack/util/shell.rb | 2 +- lib/java_buildpack/util/snake_case.rb | 2 +- lib/java_buildpack/util/space_case.rb | 2 +- lib/java_buildpack/util/spring_boot_utils.rb | 2 +- lib/java_buildpack/util/start_script.rb | 2 +- lib/java_buildpack/util/to_b.rb | 2 +- lib/java_buildpack/util/tokenized_version.rb | 2 +- rakelib/dependency_cache_task.rb | 2 +- rakelib/package.rb | 2 +- rakelib/package_task.rb | 2 +- rakelib/stage_buildpack_task.rb | 2 +- rakelib/versions_task.rb | 2 +- resources/azure_application_insights_agent/AI-Agent.xml | 5 +++-- resources/tomcat/conf/context.xml | 3 ++- resources/tomcat/conf/logging.properties | 3 ++- resources/tomcat/conf/server.xml | 3 ++- spec/application_helper.rb | 2 +- spec/bin/compile_spec.rb | 2 +- spec/bin/detect_spec.rb | 2 +- spec/bin/release_spec.rb | 2 +- spec/component_helper.rb | 2 +- spec/console_helper.rb | 2 +- spec/droplet_helper.rb | 2 +- spec/fixtures/container_groovy_logback/Alpha.java | 3 ++- .../container_groovy_logback/ch/qos/logback/pogo.groovy | 3 ++- spec/fixtures/container_groovy_main_method/Alpha.groovy | 3 ++- .../container_groovy_main_method/Application.groovy | 3 ++- .../container_groovy_main_method/directory/Beta.groovy | 3 ++- spec/fixtures/container_groovy_non_pogo/Alpha.groovy | 3 ++- spec/fixtures/container_groovy_non_pogo/Application.groovy | 3 ++- .../logback.groovy | 3 ++- spec/fixtures/container_groovy_shebang/Alpha.groovy | 3 ++- spec/fixtures/container_groovy_shebang/Application.groovy | 3 ++- .../Application.groovy | 3 ++- spec/fixtures/container_groovy_with_jars/Alpha.jar | 2 +- spec/fixtures/container_groovy_with_jars/Application.groovy | 3 ++- spec/fixtures/container_groovy_with_jars/directory/Beta.jar | 2 +- .../application-root/app/Ratpack.groovy | 3 ++- spec/fixtures/container_ratpack_staged/app/ratpack.groovy | 3 ++- .../configuration.groovy | 3 ++- .../pogo_1.groovy | 3 ++- .../pogo.groovy | 3 ++- .../container_spring_boot_cli_main_method/main.groovy | 3 ++- .../container_spring_boot_cli_main_method/pogo.groovy | 3 ++- .../container_spring_boot_cli_non_pogo/non_pogo.groovy | 3 ++- .../fixtures/container_spring_boot_cli_non_pogo/pogo.groovy | 3 ++- .../directory/pogo_4.groovy | 3 ++- .../container_spring_boot_cli_valid_app/pogo_1.groovy | 3 ++- .../container_spring_boot_cli_valid_app/pogo_2.groovy | 3 ++- .../container_spring_boot_cli_valid_app/pogo_3.groovy | 3 ++- .../.java-buildpack/tomcat/conf/context.xml | 3 ++- .../.java-buildpack/tomcat/conf/server.xml | 3 ++- .../fixtures/container_tomcat_geode_store_context_after.xml | 3 ++- spec/fixtures/container_tomcat_geode_store_server_after.xml | 3 ++- .../.java-buildpack/tomcat/conf/context.xml | 3 ++- .../fixtures/container_tomcat_redis_store_context_after.xml | 3 ++- spec/fixtures/container_tomcat_with_index/index.html | 3 ++- spec/fixtures/framework_jrebel_app_simple/rebel-remote.xml | 3 ++- .../WEB-INF/classes/rebel-remote.xml | 3 ++- .../integration_long_detect_tag/config/components.yml | 2 +- .../lib/java_buildpack/container/long_detect_tags.rb | 2 +- spec/fixtures/integration_valid/system.properties | 3 ++- spec/fixtures/test.properties | 3 ++- spec/integration_helper.rb | 2 +- spec/internet_availability_helper.rb | 2 +- spec/java_buildpack/buildpack_spec.rb | 2 +- spec/java_buildpack/buildpack_version_spec.rb | 2 +- spec/java_buildpack/component/additional_libraries_spec.rb | 2 +- spec/java_buildpack/component/application_spec.rb | 2 +- spec/java_buildpack/component/base_component_spec.rb | 2 +- spec/java_buildpack/component/droplet_spec.rb | 2 +- spec/java_buildpack/component/environment_variables_spec.rb | 2 +- spec/java_buildpack/component/extension_directories_spec.rb | 2 +- spec/java_buildpack/component/immutable_java_home_spec.rb | 2 +- spec/java_buildpack/component/java_opts_spec.rb | 2 +- spec/java_buildpack/component/modular_component_spec.rb | 2 +- spec/java_buildpack/component/mutable_java_home_spec.rb | 2 +- spec/java_buildpack/component/security_providers_spec.rb | 2 +- spec/java_buildpack/component/services_spec.rb | 2 +- .../component/versioned_dependency_component_spec.rb | 2 +- spec/java_buildpack/container/dist_zip_like_spec.rb | 2 +- spec/java_buildpack/container/dist_zip_spec.rb | 2 +- spec/java_buildpack/container/groovy_spec.rb | 2 +- spec/java_buildpack/container/java_main_spec.rb | 2 +- spec/java_buildpack/container/play_framework_spec.rb | 2 +- spec/java_buildpack/container/ratpack_spec.rb | 2 +- spec/java_buildpack/container/spring_boot_cli_spec.rb | 2 +- spec/java_buildpack/container/spring_boot_spec.rb | 2 +- .../container/tomcat/tomcat_access_logging_support_spec.rb | 2 +- .../container/tomcat/tomcat_external_configuration_spec.rb | 2 +- .../container/tomcat/tomcat_geode_store_spec.rb | 2 +- .../container/tomcat/tomcat_insight_support_spec.rb | 2 +- .../java_buildpack/container/tomcat/tomcat_instance_spec.rb | 2 +- .../container/tomcat/tomcat_lifecycle_support_spec.rb | 2 +- .../container/tomcat/tomcat_logging_support_spec.rb | 2 +- .../container/tomcat/tomcat_redis_store_spec.rb | 2 +- spec/java_buildpack/container/tomcat/tomcat_setenv_spec.rb | 2 +- spec/java_buildpack/container/tomcat_spec.rb | 2 +- spec/java_buildpack/framework/app_dynamics_agent_spec.rb | 2 +- spec/java_buildpack/framework/aspectj_weaver_agent_spec.rb | 2 +- .../framework/azure_application_insights_agent_spec.rb | 2 +- .../framework/client_certificate_mapper_spec.rb | 2 +- spec/java_buildpack/framework/container_customizer_spec.rb | 2 +- .../framework/container_security_provider_spec.rb | 2 +- .../framework/contrast_security_agent_spec.rb | 2 +- spec/java_buildpack/framework/debug_spec.rb | 2 +- .../java_buildpack/framework/dynatrace_appmon_agent_spec.rb | 2 +- spec/java_buildpack/framework/dynatrace_one_agent_spec.rb | 2 +- spec/java_buildpack/framework/elastic_apm_agent_spec.rb | 2 +- .../framework/google_stackdriver_debugger_spec.rb | 2 +- .../framework/google_stackdriver_profiler_spec.rb | 2 +- spec/java_buildpack/framework/introscope_agent_spec.rb | 2 +- spec/java_buildpack/framework/jacoco_agent_spec.rb | 2 +- .../framework/java_memory_assistant/agent_spec.rb | 2 +- .../framework/java_memory_assistant/clean_up_spec.rb | 2 +- .../java_memory_assistant/heap_dump_folder_spec.rb | 2 +- spec/java_buildpack/framework/java_memory_assistant_spec.rb | 2 +- spec/java_buildpack/framework/java_opts_spec.rb | 2 +- spec/java_buildpack/framework/java_security_spec.rb | 2 +- spec/java_buildpack/framework/jmx_spec.rb | 2 +- spec/java_buildpack/framework/jprofiler_profiler_spec.rb | 2 +- spec/java_buildpack/framework/jrebel_agent_spec.rb | 2 +- .../java_buildpack/framework/luna_security_provider_spec.rb | 2 +- spec/java_buildpack/framework/maria_db_jdbc_spec.rb | 2 +- spec/java_buildpack/framework/metric_writer_spec.rb | 2 +- spec/java_buildpack/framework/multi_buildpack_spec.rb | 2 +- spec/java_buildpack/framework/new_relic_agent_spec.rb | 2 +- spec/java_buildpack/framework/postgresql_jdbc_spec.rb | 2 +- .../framework/protect_app_security_provider_spec.rb | 2 +- .../framework/riverbed_appinternals_agent_spec.rb | 2 +- spec/java_buildpack/framework/seeker_security_agent_spec.rb | 2 +- spec/java_buildpack/framework/sky_walking_agent_spec.rb | 2 +- .../framework/spring_auto_reconfiguration_spec.rb | 2 +- spec/java_buildpack/framework/spring_insight_spec.rb | 2 +- spec/java_buildpack/framework/takipi_agent_spec.rb | 2 +- spec/java_buildpack/framework/your_kit_profiler_spec.rb | 2 +- spec/java_buildpack/jre/ibm_jre_initializer_spec.rb | 2 +- spec/java_buildpack/jre/ibm_jre_spec.rb | 2 +- spec/java_buildpack/jre/jvmkill_agent_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_jre_spec.rb | 2 +- .../jre/open_jdk_like_memory_calculator_spec.rb | 2 +- .../jre/open_jdk_like_security_providers_spec.rb | 2 +- spec/java_buildpack/jre/open_jdk_like_spec.rb | 2 +- spec/java_buildpack/logging/delegating_logger_spec.rb | 2 +- spec/java_buildpack/logging/logger_factory_spec.rb | 2 +- spec/java_buildpack/repository/configured_item_spec.rb | 2 +- spec/java_buildpack/repository/repository_index_spec.rb | 2 +- spec/java_buildpack/repository/version_resolver_spec.rb | 2 +- spec/java_buildpack/util/cache/application_cache_spec.rb | 2 +- spec/java_buildpack/util/cache/cache_factory_spec.rb | 2 +- spec/java_buildpack/util/cache/cached_file_spec.rb | 2 +- spec/java_buildpack/util/cache/download_cache_spec.rb | 2 +- .../java_buildpack/util/cache/internet_availability_spec.rb | 2 +- spec/java_buildpack/util/cache/yield_file_with_content.rb | 2 +- spec/java_buildpack/util/configuration_utils_spec.rb | 2 +- spec/java_buildpack/util/constantize_spec.rb | 2 +- spec/java_buildpack/util/filtering_pathname_spec.rb | 2 +- spec/java_buildpack/util/format_duration_spec.rb | 2 +- spec/java_buildpack/util/java_main_utils_spec.rb | 2 +- spec/java_buildpack/util/play/base_spec.rb | 2 +- spec/java_buildpack/util/play/factory_spec.rb | 2 +- spec/java_buildpack/util/play/post22_dist_spec.rb | 2 +- spec/java_buildpack/util/play/post22_spec.rb | 2 +- spec/java_buildpack/util/play/post22_staged_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_dist_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_spec.rb | 2 +- spec/java_buildpack/util/play/pre22_staged_spec.rb | 2 +- spec/java_buildpack/util/properties_spec.rb | 2 +- spec/java_buildpack/util/ratpack_utils_spec.rb | 2 +- spec/java_buildpack/util/sanitize_spec.rb | 2 +- spec/java_buildpack/util/shell_spec.rb | 2 +- spec/java_buildpack/util/spring_boot_utils_spec.rb | 2 +- spec/java_buildpack/util/tokenized_version_spec.rb | 2 +- spec/logging_helper.rb | 2 +- spec/memory_limit_helper.rb | 2 +- spec/spec_helper.rb | 2 +- 371 files changed, 414 insertions(+), 377 deletions(-) diff --git a/.idea/copyright/Apache_License__Version_2_0.xml b/.idea/copyright/Apache_License__Version_2_0.xml index 893ada61a7..34853bafd0 100644 --- a/.idea/copyright/Apache_License__Version_2_0.xml +++ b/.idea/copyright/Apache_License__Version_2_0.xml @@ -1,9 +1,6 @@ - \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f352b769b5..3a36fc75bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ Please carefully follow the whitespace and formatting conventions already presen ## Add Apache license header to all new classes ```ruby # Cloud Foundry Java Buildpack -# Copyright 2013-2016 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -64,10 +64,10 @@ Always check the date range in the license header. For example, if you've modifi # Copyright 2013 the original author or authors. ``` -then be sure to update it to 2016 appropriately +then be sure to update it to 2020 appropriately ```ruby - # Copyright 2013-2016 the original author or authors. + # Copyright 2013-2020 the original author or authors. ``` ## Submit RSpec test cases for all behavior changes diff --git a/Rakefile b/Rakefile index 715d723e40..d5a096ac18 100644 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/compile b/bin/compile index be7589efc4..c0bf2ab8c4 100755 --- a/bin/compile +++ b/bin/compile @@ -2,7 +2,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/detect b/bin/detect index 44d43d71af..e0afc6f79e 100755 --- a/bin/detect +++ b/bin/detect @@ -2,7 +2,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/finalize b/bin/finalize index 2a0330f27e..4fa83c2f1c 100755 --- a/bin/finalize +++ b/bin/finalize @@ -2,7 +2,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/bin/release b/bin/release index d301964313..95107caed4 100755 --- a/bin/release +++ b/bin/release @@ -2,7 +2,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/auto-merge.sh b/ci/auto-merge.sh index b60c842e3c..7437d2654c 100755 --- a/ci/auto-merge.sh +++ b/ci/auto-merge.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/auto-merge.yml b/ci/auto-merge.yml index eed658e8de..a1fbfe2625 100644 --- a/ci/auto-merge.yml +++ b/ci/auto-merge.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/package-test.sh b/ci/package-test.sh index 3731327739..e50addeb73 100755 --- a/ci/package-test.sh +++ b/ci/package-test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/package-test.yml b/ci/package-test.yml index fb2800e729..733e14ebf5 100644 --- a/ci/package-test.yml +++ b/ci/package-test.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/unit-test.sh b/ci/unit-test.sh index df68193a40..bcfd1c4e9e 100755 --- a/ci/unit-test.sh +++ b/ci/unit-test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/unit-test.yml b/ci/unit-test.yml index bf6d15e328..b367ff13be 100644 --- a/ci/unit-test.yml +++ b/ci/unit-test.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-json.sh b/ci/versions-json.sh index b8572ae50b..ae6b06888e 100755 --- a/ci/versions-json.sh +++ b/ci/versions-json.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-json.yml b/ci/versions-json.yml index 227f62b451..69f283fa3d 100644 --- a/ci/versions-json.yml +++ b/ci/versions-json.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-markdown.sh b/ci/versions-markdown.sh index 7b737cb001..f4d377a639 100755 --- a/ci/versions-markdown.sh +++ b/ci/versions-markdown.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-markdown.yml b/ci/versions-markdown.yml index cc3a5262de..e8b68817f9 100644 --- a/ci/versions-markdown.yml +++ b/ci/versions-markdown.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-yaml.sh b/ci/versions-yaml.sh index 38c0445efd..14edffeb4c 100755 --- a/ci/versions-yaml.sh +++ b/ci/versions-yaml.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions-yaml.yml b/ci/versions-yaml.yml index e6699ae557..46c45eb6aa 100644 --- a/ci/versions-yaml.yml +++ b/ci/versions-yaml.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions.sh b/ci/versions.sh index 982ce74cef..9c12787162 100755 --- a/ci/versions.sh +++ b/ci/versions.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/ci/versions.yml b/ci/versions.yml index f644e51e40..4a0401f01a 100644 --- a/ci/versions.yml +++ b/ci/versions.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 20eb279456..94ce3b8bc3 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/aspectj_weaver_agent.yml b/config/aspectj_weaver_agent.yml index 891c9ff1d7..5fdc234969 100644 --- a/config/aspectj_weaver_agent.yml +++ b/config/aspectj_weaver_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/azure_application_insights_agent.yml b/config/azure_application_insights_agent.yml index c1e51023ca..1827271bcd 100644 --- a/config/azure_application_insights_agent.yml +++ b/config/azure_application_insights_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/cache.yml b/config/cache.yml index e2b48f092b..9f2be8f19f 100644 --- a/config/cache.yml +++ b/config/cache.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/client_certificate_mapper.yml b/config/client_certificate_mapper.yml index ea60acd0b3..a306eaba03 100644 --- a/config/client_certificate_mapper.yml +++ b/config/client_certificate_mapper.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/components.yml b/config/components.yml index 72d10418a7..660135685b 100644 --- a/config/components.yml +++ b/config/components.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/container_customizer.yml b/config/container_customizer.yml index 4a62ca1bec..cfa6e00b5b 100644 --- a/config/container_customizer.yml +++ b/config/container_customizer.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/container_security_provider.yml b/config/container_security_provider.yml index 912a43a109..f4d88d84fe 100644 --- a/config/container_security_provider.yml +++ b/config/container_security_provider.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index e3fd6bf7db..09568052b5 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/debug.yml b/config/debug.yml index 8883a8d3c0..186de94881 100644 --- a/config/debug.yml +++ b/config/debug.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/dynatrace_appmon_agent.yml b/config/dynatrace_appmon_agent.yml index 7849ebd7ed..79126c66a3 100644 --- a/config/dynatrace_appmon_agent.yml +++ b/config/dynatrace_appmon_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/elastic_apm_agent.yml b/config/elastic_apm_agent.yml index c41ace3ffa..e9db8ffcf9 100644 --- a/config/elastic_apm_agent.yml +++ b/config/elastic_apm_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/google_stackdriver_debugger.yml b/config/google_stackdriver_debugger.yml index 99814bb547..8c4a521661 100644 --- a/config/google_stackdriver_debugger.yml +++ b/config/google_stackdriver_debugger.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/google_stackdriver_profiler.yml b/config/google_stackdriver_profiler.yml index 5ec94f84a7..470051e04e 100644 --- a/config/google_stackdriver_profiler.yml +++ b/config/google_stackdriver_profiler.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/groovy.yml b/config/groovy.yml index 649c9d3a78..bd697ccd6e 100644 --- a/config/groovy.yml +++ b/config/groovy.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/ibm_jre.yml b/config/ibm_jre.yml index 94acccde88..39b5c3d944 100644 --- a/config/ibm_jre.yml +++ b/config/ibm_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2017 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index 6740730d70..70f69b547d 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/jacoco_agent.yml b/config/jacoco_agent.yml index 449a4142d7..d26b0bec05 100644 --- a/config/jacoco_agent.yml +++ b/config/jacoco_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/java_main.yml b/config/java_main.yml index 481d771fc4..bcd986be62 100644 --- a/config/java_main.yml +++ b/config/java_main.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/java_memory_assistant.yml b/config/java_memory_assistant.yml index c4604fd873..2f94cf408a 100644 --- a/config/java_memory_assistant.yml +++ b/config/java_memory_assistant.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/java_opts.yml b/config/java_opts.yml index 1fd2f7e1ca..60a38d8b7d 100644 --- a/config/java_opts.yml +++ b/config/java_opts.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/jmx.yml b/config/jmx.yml index 68b365c2d5..12b75b24b3 100644 --- a/config/jmx.yml +++ b/config/jmx.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/jprofiler_profiler.yml b/config/jprofiler_profiler.yml index 1fed02e236..953b0cca0b 100644 --- a/config/jprofiler_profiler.yml +++ b/config/jprofiler_profiler.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/jrebel_agent.yml b/config/jrebel_agent.yml index 78c1c69703..fd197b69eb 100644 --- a/config/jrebel_agent.yml +++ b/config/jrebel_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/logging.yml b/config/logging.yml index 19dd8c9c86..1bb256393f 100644 --- a/config/logging.yml +++ b/config/logging.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index ae3e7806de..352b8265eb 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/maria_db_jdbc.yml b/config/maria_db_jdbc.yml index 8d47924223..d13bf8d749 100644 --- a/config/maria_db_jdbc.yml +++ b/config/maria_db_jdbc.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/metric_writer.yml b/config/metric_writer.yml index 7a96b43a96..7d833ef384 100644 --- a/config/metric_writer.yml +++ b/config/metric_writer.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/new_relic_agent.yml b/config/new_relic_agent.yml index 1de53a56b5..1e36268f01 100644 --- a/config/new_relic_agent.yml +++ b/config/new_relic_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index d6d2611a7a..29947ec635 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index dd383e409a..df91cc2e26 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/postgresql_jdbc.yml b/config/postgresql_jdbc.yml index 885af2a046..2238a6ba0c 100644 --- a/config/postgresql_jdbc.yml +++ b/config/postgresql_jdbc.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/protect_app_security_provider.yml b/config/protect_app_security_provider.yml index 4f4b0b79e5..2f65c2475d 100644 --- a/config/protect_app_security_provider.yml +++ b/config/protect_app_security_provider.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2016 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/repository.yml b/config/repository.yml index 4951f18507..8ec03e178a 100644 --- a/config/repository.yml +++ b/config/repository.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/riverbed_appinternals_agent.yml b/config/riverbed_appinternals_agent.yml index 27b5ff97b9..ba0ad4f3eb 100644 --- a/config/riverbed_appinternals_agent.yml +++ b/config/riverbed_appinternals_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/sap_machine_jre.yml b/config/sap_machine_jre.yml index a69a06032a..ef8fb554fb 100644 --- a/config/sap_machine_jre.yml +++ b/config/sap_machine_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2018 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/sky_walking_agent.yml b/config/sky_walking_agent.yml index 1ac44a211c..7ca9923f7d 100644 --- a/config/sky_walking_agent.yml +++ b/config/sky_walking_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/spring_auto_reconfiguration.yml b/config/spring_auto_reconfiguration.yml index 9825c39179..14e976bff7 100644 --- a/config/spring_auto_reconfiguration.yml +++ b/config/spring_auto_reconfiguration.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/spring_boot_cli.yml b/config/spring_boot_cli.yml index c7d35462c8..54d4c8c5bd 100644 --- a/config/spring_boot_cli.yml +++ b/config/spring_boot_cli.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/takipi_agent.yml b/config/takipi_agent.yml index cda0be6cfb..dd8407034e 100644 --- a/config/takipi_agent.yml +++ b/config/takipi_agent.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/tomcat.yml b/config/tomcat.yml index 8a38110674..bd31372868 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/your_kit_profiler.yml b/config/your_kit_profiler.yml index 3a4a77419d..8384316fe7 100644 --- a/config/your_kit_profiler.yml +++ b/config/your_kit_profiler.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 91742dca29..231b659ccb 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack.rb b/lib/java_buildpack.rb index ed3243e83f..aa7f6e6e60 100644 --- a/lib/java_buildpack.rb +++ b/lib/java_buildpack.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 03aea901f9..a06a3d4049 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index ef19274751..76501b7f5c 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component.rb b/lib/java_buildpack/component.rb index 512d16ff55..4dce9ef091 100644 --- a/lib/java_buildpack/component.rb +++ b/lib/java_buildpack/component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/additional_libraries.rb b/lib/java_buildpack/component/additional_libraries.rb index e466be8edc..81ae6fc231 100644 --- a/lib/java_buildpack/component/additional_libraries.rb +++ b/lib/java_buildpack/component/additional_libraries.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/application.rb b/lib/java_buildpack/component/application.rb index 20c5da5416..8dfb78409a 100644 --- a/lib/java_buildpack/component/application.rb +++ b/lib/java_buildpack/component/application.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 6af4d74517..2f43e3d565 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/droplet.rb b/lib/java_buildpack/component/droplet.rb index 181c01507d..d570f2e49e 100644 --- a/lib/java_buildpack/component/droplet.rb +++ b/lib/java_buildpack/component/droplet.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/environment_variables.rb b/lib/java_buildpack/component/environment_variables.rb index 1789bc51fc..a8ca815b53 100644 --- a/lib/java_buildpack/component/environment_variables.rb +++ b/lib/java_buildpack/component/environment_variables.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/extension_directories.rb b/lib/java_buildpack/component/extension_directories.rb index 5d419dfef1..836ee8d097 100644 --- a/lib/java_buildpack/component/extension_directories.rb +++ b/lib/java_buildpack/component/extension_directories.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/immutable_java_home.rb b/lib/java_buildpack/component/immutable_java_home.rb index fc7aac42c5..7619dc3f08 100644 --- a/lib/java_buildpack/component/immutable_java_home.rb +++ b/lib/java_buildpack/component/immutable_java_home.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/java_opts.rb b/lib/java_buildpack/component/java_opts.rb index 15fdabdf7b..1dee29c665 100644 --- a/lib/java_buildpack/component/java_opts.rb +++ b/lib/java_buildpack/component/java_opts.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/modular_component.rb b/lib/java_buildpack/component/modular_component.rb index afe5b2dfce..e718603867 100644 --- a/lib/java_buildpack/component/modular_component.rb +++ b/lib/java_buildpack/component/modular_component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index 6152a19c12..48b7a4bd92 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/networking.rb b/lib/java_buildpack/component/networking.rb index abbe922fd3..92b29f7779 100644 --- a/lib/java_buildpack/component/networking.rb +++ b/lib/java_buildpack/component/networking.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/root_libraries.rb b/lib/java_buildpack/component/root_libraries.rb index bc378ca6ad..dfd44d20e2 100644 --- a/lib/java_buildpack/component/root_libraries.rb +++ b/lib/java_buildpack/component/root_libraries.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/security_providers.rb b/lib/java_buildpack/component/security_providers.rb index c9388ee9a3..f2e98503ef 100644 --- a/lib/java_buildpack/component/security_providers.rb +++ b/lib/java_buildpack/component/security_providers.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/services.rb b/lib/java_buildpack/component/services.rb index 7c8a55a386..c5759df462 100644 --- a/lib/java_buildpack/component/services.rb +++ b/lib/java_buildpack/component/services.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/component/versioned_dependency_component.rb b/lib/java_buildpack/component/versioned_dependency_component.rb index 0ca0faea51..545390574f 100644 --- a/lib/java_buildpack/component/versioned_dependency_component.rb +++ b/lib/java_buildpack/component/versioned_dependency_component.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container.rb b/lib/java_buildpack/container.rb index 73287ff7ba..ae680f7768 100644 --- a/lib/java_buildpack/container.rb +++ b/lib/java_buildpack/container.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/dist_zip.rb b/lib/java_buildpack/container/dist_zip.rb index 88439d49dc..0a2c3190a1 100644 --- a/lib/java_buildpack/container/dist_zip.rb +++ b/lib/java_buildpack/container/dist_zip.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 60ae1997c5..d38d3aded3 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/groovy.rb b/lib/java_buildpack/container/groovy.rb index 54fdd84a81..a60de4040f 100644 --- a/lib/java_buildpack/container/groovy.rb +++ b/lib/java_buildpack/container/groovy.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index d312f61815..9a1896f9bc 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/play_framework.rb b/lib/java_buildpack/container/play_framework.rb index fe56c78757..cdb3bd26b3 100644 --- a/lib/java_buildpack/container/play_framework.rb +++ b/lib/java_buildpack/container/play_framework.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/ratpack.rb b/lib/java_buildpack/container/ratpack.rb index 2ee28e719d..8f6858f4f0 100644 --- a/lib/java_buildpack/container/ratpack.rb +++ b/lib/java_buildpack/container/ratpack.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/spring_boot.rb b/lib/java_buildpack/container/spring_boot.rb index 0bc7ad293d..ada6321aac 100644 --- a/lib/java_buildpack/container/spring_boot.rb +++ b/lib/java_buildpack/container/spring_boot.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/spring_boot_cli.rb b/lib/java_buildpack/container/spring_boot_cli.rb index 838eb30b47..54a78e4519 100644 --- a/lib/java_buildpack/container/spring_boot_cli.rb +++ b/lib/java_buildpack/container/spring_boot_cli.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 12dd509b14..43a787a818 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb index 113ce6e3e8..96e910da1f 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_access_logging_support.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb index 65d3f43886..8cec475e6f 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_external_configuration.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index f7166a020b..406bcc384d 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb index 4ae3e37fe1..fe6bbe0a68 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_insight_support.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index 58554062af..cd78ae1df4 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb index 74b0a8709d..c3c7c09c78 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_lifecycle_support.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb index 10deced444..93c4c1e9ed 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_logging_support.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb index 99decee039..a60d1633c3 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_redis_store.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_setenv.rb b/lib/java_buildpack/container/tomcat/tomcat_setenv.rb index 915af92806..a91e9e9824 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_setenv.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_setenv.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat/tomcat_utils.rb b/lib/java_buildpack/container/tomcat/tomcat_utils.rb index d46e8fa47b..a7ee0ad48c 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_utils.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework.rb b/lib/java_buildpack/framework.rb index 01345bb049..43da670f97 100644 --- a/lib/java_buildpack/framework.rb +++ b/lib/java_buildpack/framework.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 1e00c4312c..39dae9badb 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/aspectj_weaver_agent.rb b/lib/java_buildpack/framework/aspectj_weaver_agent.rb index d0b0e16866..e49ae0d688 100644 --- a/lib/java_buildpack/framework/aspectj_weaver_agent.rb +++ b/lib/java_buildpack/framework/aspectj_weaver_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/azure_application_insights_agent.rb b/lib/java_buildpack/framework/azure_application_insights_agent.rb index ac14170029..f47d21527f 100644 --- a/lib/java_buildpack/framework/azure_application_insights_agent.rb +++ b/lib/java_buildpack/framework/azure_application_insights_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/client_certificate_mapper.rb b/lib/java_buildpack/framework/client_certificate_mapper.rb index 0b0b0ba8ea..599d3a6ba2 100644 --- a/lib/java_buildpack/framework/client_certificate_mapper.rb +++ b/lib/java_buildpack/framework/client_certificate_mapper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/container_customizer.rb b/lib/java_buildpack/framework/container_customizer.rb index a1c6fc731b..044079877e 100644 --- a/lib/java_buildpack/framework/container_customizer.rb +++ b/lib/java_buildpack/framework/container_customizer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/container_security_provider.rb b/lib/java_buildpack/framework/container_security_provider.rb index 7df14d6c37..fd98af2cdd 100644 --- a/lib/java_buildpack/framework/container_security_provider.rb +++ b/lib/java_buildpack/framework/container_security_provider.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/contrast_security_agent.rb b/lib/java_buildpack/framework/contrast_security_agent.rb index f2fc4ab379..9d5d3fb63c 100644 --- a/lib/java_buildpack/framework/contrast_security_agent.rb +++ b/lib/java_buildpack/framework/contrast_security_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/debug.rb b/lib/java_buildpack/framework/debug.rb index ba497e03ec..fe13734b2a 100644 --- a/lib/java_buildpack/framework/debug.rb +++ b/lib/java_buildpack/framework/debug.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb index b1f65f10ff..d19a71ddb6 100644 --- a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index cb1785484d..adb83b3bea 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/elastic_apm_agent.rb b/lib/java_buildpack/framework/elastic_apm_agent.rb index 6199385c3b..fb25d05775 100644 --- a/lib/java_buildpack/framework/elastic_apm_agent.rb +++ b/lib/java_buildpack/framework/elastic_apm_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2018 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/google_stackdriver_debugger.rb b/lib/java_buildpack/framework/google_stackdriver_debugger.rb index cedbd80f91..e8e519cbd8 100644 --- a/lib/java_buildpack/framework/google_stackdriver_debugger.rb +++ b/lib/java_buildpack/framework/google_stackdriver_debugger.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/google_stackdriver_profiler.rb b/lib/java_buildpack/framework/google_stackdriver_profiler.rb index be7239b919..8be7fa6f7f 100644 --- a/lib/java_buildpack/framework/google_stackdriver_profiler.rb +++ b/lib/java_buildpack/framework/google_stackdriver_profiler.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index 75abbc32f5..25503d69e8 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/jacoco_agent.rb b/lib/java_buildpack/framework/jacoco_agent.rb index bf4455cfeb..e585776b85 100644 --- a/lib/java_buildpack/framework/jacoco_agent.rb +++ b/lib/java_buildpack/framework/jacoco_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_memory_assistant.rb b/lib/java_buildpack/framework/java_memory_assistant.rb index d5e9000bb5..a9bddea2b9 100644 --- a/lib/java_buildpack/framework/java_memory_assistant.rb +++ b/lib/java_buildpack/framework/java_memory_assistant.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_memory_assistant/agent.rb b/lib/java_buildpack/framework/java_memory_assistant/agent.rb index 7e5b4bab70..89054fc542 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/agent.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb b/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb index 02864a8965..aa5c6acff1 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/clean_up.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb index 1dc93c9713..dcdcb0dd2a 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/heap_dump_folder.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index 2c4d3b28eb..373ca796c7 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/java_security.rb b/lib/java_buildpack/framework/java_security.rb index 40aeac999b..3f58245a32 100644 --- a/lib/java_buildpack/framework/java_security.rb +++ b/lib/java_buildpack/framework/java_security.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/jmx.rb b/lib/java_buildpack/framework/jmx.rb index 65da1f0f11..47171d88f1 100644 --- a/lib/java_buildpack/framework/jmx.rb +++ b/lib/java_buildpack/framework/jmx.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/jprofiler_profiler.rb b/lib/java_buildpack/framework/jprofiler_profiler.rb index 561d382658..71e942beb0 100644 --- a/lib/java_buildpack/framework/jprofiler_profiler.rb +++ b/lib/java_buildpack/framework/jprofiler_profiler.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/jrebel_agent.rb b/lib/java_buildpack/framework/jrebel_agent.rb index d1e510da37..1b09fa3ed0 100644 --- a/lib/java_buildpack/framework/jrebel_agent.rb +++ b/lib/java_buildpack/framework/jrebel_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index cdfac61140..748320b50c 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/maria_db_jdbc.rb b/lib/java_buildpack/framework/maria_db_jdbc.rb index db8806abe8..628010d1e7 100644 --- a/lib/java_buildpack/framework/maria_db_jdbc.rb +++ b/lib/java_buildpack/framework/maria_db_jdbc.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/metric_writer.rb b/lib/java_buildpack/framework/metric_writer.rb index 6dd251ac74..5eb68a5162 100644 --- a/lib/java_buildpack/framework/metric_writer.rb +++ b/lib/java_buildpack/framework/metric_writer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/multi_buildpack.rb b/lib/java_buildpack/framework/multi_buildpack.rb index 0da03820c7..0367e3bc87 100644 --- a/lib/java_buildpack/framework/multi_buildpack.rb +++ b/lib/java_buildpack/framework/multi_buildpack.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/new_relic_agent.rb b/lib/java_buildpack/framework/new_relic_agent.rb index f3d21d25c0..8aa764276d 100644 --- a/lib/java_buildpack/framework/new_relic_agent.rb +++ b/lib/java_buildpack/framework/new_relic_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/postgresql_jdbc.rb b/lib/java_buildpack/framework/postgresql_jdbc.rb index 576edf45eb..71c4846432 100644 --- a/lib/java_buildpack/framework/postgresql_jdbc.rb +++ b/lib/java_buildpack/framework/postgresql_jdbc.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/protect_app_security_provider.rb b/lib/java_buildpack/framework/protect_app_security_provider.rb index 583080212f..b2a0c5eadb 100644 --- a/lib/java_buildpack/framework/protect_app_security_provider.rb +++ b/lib/java_buildpack/framework/protect_app_security_provider.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2016 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb index 4167c440a6..f8e832f45d 100644 --- a/lib/java_buildpack/framework/riverbed_appinternals_agent.rb +++ b/lib/java_buildpack/framework/riverbed_appinternals_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/seeker_security_provider.rb b/lib/java_buildpack/framework/seeker_security_provider.rb index c45f5619ed..face7bc672 100644 --- a/lib/java_buildpack/framework/seeker_security_provider.rb +++ b/lib/java_buildpack/framework/seeker_security_provider.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2017 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/sky_walking_agent.rb b/lib/java_buildpack/framework/sky_walking_agent.rb index 527a61fcb6..8e0ba3bef1 100644 --- a/lib/java_buildpack/framework/sky_walking_agent.rb +++ b/lib/java_buildpack/framework/sky_walking_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 00e9651f09..295417371b 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/spring_insight.rb b/lib/java_buildpack/framework/spring_insight.rb index 5f3deae416..9adcf32548 100644 --- a/lib/java_buildpack/framework/spring_insight.rb +++ b/lib/java_buildpack/framework/spring_insight.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index b50deffa17..4199455940 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/framework/your_kit_profiler.rb b/lib/java_buildpack/framework/your_kit_profiler.rb index db7f6dfd9d..1d648f0ba3 100644 --- a/lib/java_buildpack/framework/your_kit_profiler.rb +++ b/lib/java_buildpack/framework/your_kit_profiler.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre.rb b/lib/java_buildpack/jre.rb index 4f69bd76ff..44ee90454b 100644 --- a/lib/java_buildpack/jre.rb +++ b/lib/java_buildpack/jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/graal_vm_jre.rb b/lib/java_buildpack/jre/graal_vm_jre.rb index debaccb0eb..3623238579 100644 --- a/lib/java_buildpack/jre/graal_vm_jre.rb +++ b/lib/java_buildpack/jre/graal_vm_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2018 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/ibm_jre.rb b/lib/java_buildpack/jre/ibm_jre.rb index ed5dc81e95..cc64e2dac0 100644 --- a/lib/java_buildpack/jre/ibm_jre.rb +++ b/lib/java_buildpack/jre/ibm_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2017 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/ibm_jre_initializer.rb b/lib/java_buildpack/jre/ibm_jre_initializer.rb index 09120ed9b0..57de71f64f 100644 --- a/lib/java_buildpack/jre/ibm_jre_initializer.rb +++ b/lib/java_buildpack/jre/ibm_jre_initializer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2017 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/jvmkill_agent.rb b/lib/java_buildpack/jre/jvmkill_agent.rb index 0438748bf2..e4897bd972 100644 --- a/lib/java_buildpack/jre/jvmkill_agent.rb +++ b/lib/java_buildpack/jre/jvmkill_agent.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2016 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_jre.rb b/lib/java_buildpack/jre/open_jdk_jre.rb index 9ff5ce4d27..7f962d119c 100644 --- a/lib/java_buildpack/jre/open_jdk_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like.rb b/lib/java_buildpack/jre/open_jdk_like.rb index 5b4fa3e1ef..9cdd7aa68f 100644 --- a/lib/java_buildpack/jre/open_jdk_like.rb +++ b/lib/java_buildpack/jre/open_jdk_like.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index b5ea6fa41c..eb41fe2562 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index 70c08f0b17..c760538294 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb index 31872049c3..75b2a443a7 100644 --- a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb +++ b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/oracle_jre.rb b/lib/java_buildpack/jre/oracle_jre.rb index a1312219c4..b229a6a3bf 100644 --- a/lib/java_buildpack/jre/oracle_jre.rb +++ b/lib/java_buildpack/jre/oracle_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/sap_machine_jre.rb b/lib/java_buildpack/jre/sap_machine_jre.rb index 87770883fb..73243d0564 100644 --- a/lib/java_buildpack/jre/sap_machine_jre.rb +++ b/lib/java_buildpack/jre/sap_machine_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2018 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/jre/zulu_jre.rb b/lib/java_buildpack/jre/zulu_jre.rb index 44704181c1..ab5067162b 100755 --- a/lib/java_buildpack/jre/zulu_jre.rb +++ b/lib/java_buildpack/jre/zulu_jre.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2016 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/logging.rb b/lib/java_buildpack/logging.rb index 58958e0c09..cf4f1f41c5 100644 --- a/lib/java_buildpack/logging.rb +++ b/lib/java_buildpack/logging.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/logging/delegating_logger.rb b/lib/java_buildpack/logging/delegating_logger.rb index b2ce8dff31..070e1db734 100644 --- a/lib/java_buildpack/logging/delegating_logger.rb +++ b/lib/java_buildpack/logging/delegating_logger.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/logging/logger_factory.rb b/lib/java_buildpack/logging/logger_factory.rb index 503308d857..4eccbde561 100644 --- a/lib/java_buildpack/logging/logger_factory.rb +++ b/lib/java_buildpack/logging/logger_factory.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository.rb b/lib/java_buildpack/repository.rb index 4acde691fa..94d7b586bc 100644 --- a/lib/java_buildpack/repository.rb +++ b/lib/java_buildpack/repository.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/configured_item.rb b/lib/java_buildpack/repository/configured_item.rb index 02f19d9ced..7655d5eb04 100644 --- a/lib/java_buildpack/repository/configured_item.rb +++ b/lib/java_buildpack/repository/configured_item.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index e80ba63c3f..06b226dec5 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/repository/version_resolver.rb b/lib/java_buildpack/repository/version_resolver.rb index 6e2a6be7ec..6d6d25838e 100644 --- a/lib/java_buildpack/repository/version_resolver.rb +++ b/lib/java_buildpack/repository/version_resolver.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util.rb b/lib/java_buildpack/util.rb index 49b1c2cab1..8815609f9f 100644 --- a/lib/java_buildpack/util.rb +++ b/lib/java_buildpack/util.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache.rb b/lib/java_buildpack/util/cache.rb index b5a9abcc9f..8258724e28 100644 --- a/lib/java_buildpack/util/cache.rb +++ b/lib/java_buildpack/util/cache.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/application_cache.rb b/lib/java_buildpack/util/cache/application_cache.rb index cfc31f6ec2..2a38962724 100644 --- a/lib/java_buildpack/util/cache/application_cache.rb +++ b/lib/java_buildpack/util/cache/application_cache.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/cache_factory.rb b/lib/java_buildpack/util/cache/cache_factory.rb index 6fe9a97503..628dbc5211 100644 --- a/lib/java_buildpack/util/cache/cache_factory.rb +++ b/lib/java_buildpack/util/cache/cache_factory.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/cached_file.rb b/lib/java_buildpack/util/cache/cached_file.rb index 7e77dd5197..dab3030f47 100644 --- a/lib/java_buildpack/util/cache/cached_file.rb +++ b/lib/java_buildpack/util/cache/cached_file.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 9b513242db..a961097bc0 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/inferred_network_failure.rb b/lib/java_buildpack/util/cache/inferred_network_failure.rb index 4b94ba7c01..ae67e8be66 100644 --- a/lib/java_buildpack/util/cache/inferred_network_failure.rb +++ b/lib/java_buildpack/util/cache/inferred_network_failure.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/cache/internet_availability.rb b/lib/java_buildpack/util/cache/internet_availability.rb index b66c397a0b..b6d1b8fe1f 100644 --- a/lib/java_buildpack/util/cache/internet_availability.rb +++ b/lib/java_buildpack/util/cache/internet_availability.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/class_file_utils.rb b/lib/java_buildpack/util/class_file_utils.rb index a8750164c9..5b7e6abf6b 100644 --- a/lib/java_buildpack/util/class_file_utils.rb +++ b/lib/java_buildpack/util/class_file_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/colorize.rb b/lib/java_buildpack/util/colorize.rb index 0db820ede4..96115b1cd0 100644 --- a/lib/java_buildpack/util/colorize.rb +++ b/lib/java_buildpack/util/colorize.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 977b32998f..2f51398ded 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/constantize.rb b/lib/java_buildpack/util/constantize.rb index 74ac83fa20..535c9ac407 100644 --- a/lib/java_buildpack/util/constantize.rb +++ b/lib/java_buildpack/util/constantize.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/dash_case.rb b/lib/java_buildpack/util/dash_case.rb index 539a9f030e..943429ebe8 100644 --- a/lib/java_buildpack/util/dash_case.rb +++ b/lib/java_buildpack/util/dash_case.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/file_enumerable.rb b/lib/java_buildpack/util/file_enumerable.rb index 74b1ca1642..db54bd974b 100644 --- a/lib/java_buildpack/util/file_enumerable.rb +++ b/lib/java_buildpack/util/file_enumerable.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/filtering_pathname.rb b/lib/java_buildpack/util/filtering_pathname.rb index b2fbf9ad98..2a71c80279 100644 --- a/lib/java_buildpack/util/filtering_pathname.rb +++ b/lib/java_buildpack/util/filtering_pathname.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/find_single_directory.rb b/lib/java_buildpack/util/find_single_directory.rb index 01c0e41841..fe15adbd0d 100644 --- a/lib/java_buildpack/util/find_single_directory.rb +++ b/lib/java_buildpack/util/find_single_directory.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/format_duration.rb b/lib/java_buildpack/util/format_duration.rb index 20941eed0f..2a8d2f56c2 100644 --- a/lib/java_buildpack/util/format_duration.rb +++ b/lib/java_buildpack/util/format_duration.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/groovy_utils.rb b/lib/java_buildpack/util/groovy_utils.rb index f539005ca9..98a0ca089e 100644 --- a/lib/java_buildpack/util/groovy_utils.rb +++ b/lib/java_buildpack/util/groovy_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/jar_finder.rb b/lib/java_buildpack/util/jar_finder.rb index 9929755307..779985999a 100644 --- a/lib/java_buildpack/util/jar_finder.rb +++ b/lib/java_buildpack/util/jar_finder.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/java_main_utils.rb b/lib/java_buildpack/util/java_main_utils.rb index d77197d720..4dd11c12e8 100644 --- a/lib/java_buildpack/util/java_main_utils.rb +++ b/lib/java_buildpack/util/java_main_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play.rb b/lib/java_buildpack/util/play.rb index 185fdde87a..9e9f0a5dbb 100644 --- a/lib/java_buildpack/util/play.rb +++ b/lib/java_buildpack/util/play.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/base.rb b/lib/java_buildpack/util/play/base.rb index 7dcc59454f..c66a75b5b8 100644 --- a/lib/java_buildpack/util/play/base.rb +++ b/lib/java_buildpack/util/play/base.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/factory.rb b/lib/java_buildpack/util/play/factory.rb index de52ca31e8..10f2b35348 100644 --- a/lib/java_buildpack/util/play/factory.rb +++ b/lib/java_buildpack/util/play/factory.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/post22.rb b/lib/java_buildpack/util/play/post22.rb index 9eb042b3d9..18177af91d 100644 --- a/lib/java_buildpack/util/play/post22.rb +++ b/lib/java_buildpack/util/play/post22.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/post22_dist.rb b/lib/java_buildpack/util/play/post22_dist.rb index 04cf3c40ec..8e5748980f 100644 --- a/lib/java_buildpack/util/play/post22_dist.rb +++ b/lib/java_buildpack/util/play/post22_dist.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/post22_staged.rb b/lib/java_buildpack/util/play/post22_staged.rb index 2875f75eb3..2c49728a61 100644 --- a/lib/java_buildpack/util/play/post22_staged.rb +++ b/lib/java_buildpack/util/play/post22_staged.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/pre22.rb b/lib/java_buildpack/util/play/pre22.rb index d2f1197f64..9bdd3f7e0f 100644 --- a/lib/java_buildpack/util/play/pre22.rb +++ b/lib/java_buildpack/util/play/pre22.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/pre22_dist.rb b/lib/java_buildpack/util/play/pre22_dist.rb index 2614a40caa..65bea1dc4c 100644 --- a/lib/java_buildpack/util/play/pre22_dist.rb +++ b/lib/java_buildpack/util/play/pre22_dist.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/play/pre22_staged.rb b/lib/java_buildpack/util/play/pre22_staged.rb index a4de33e84a..583a988409 100644 --- a/lib/java_buildpack/util/play/pre22_staged.rb +++ b/lib/java_buildpack/util/play/pre22_staged.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/properties.rb b/lib/java_buildpack/util/properties.rb index 5e35e7551d..d3315c6544 100644 --- a/lib/java_buildpack/util/properties.rb +++ b/lib/java_buildpack/util/properties.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/qualify_path.rb b/lib/java_buildpack/util/qualify_path.rb index 52a360a2f9..5d15028892 100644 --- a/lib/java_buildpack/util/qualify_path.rb +++ b/lib/java_buildpack/util/qualify_path.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/ratpack_utils.rb b/lib/java_buildpack/util/ratpack_utils.rb index 571d445288..064da366bd 100644 --- a/lib/java_buildpack/util/ratpack_utils.rb +++ b/lib/java_buildpack/util/ratpack_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index 4673135783..29253e07fd 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/shell.rb b/lib/java_buildpack/util/shell.rb index f0a768f80e..d8a0a1035b 100644 --- a/lib/java_buildpack/util/shell.rb +++ b/lib/java_buildpack/util/shell.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/snake_case.rb b/lib/java_buildpack/util/snake_case.rb index 3a0f28f94b..115ea5f56c 100644 --- a/lib/java_buildpack/util/snake_case.rb +++ b/lib/java_buildpack/util/snake_case.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/space_case.rb b/lib/java_buildpack/util/space_case.rb index 12a02f226e..3183807802 100644 --- a/lib/java_buildpack/util/space_case.rb +++ b/lib/java_buildpack/util/space_case.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/spring_boot_utils.rb b/lib/java_buildpack/util/spring_boot_utils.rb index eeef1d9d70..c6ea5535dc 100644 --- a/lib/java_buildpack/util/spring_boot_utils.rb +++ b/lib/java_buildpack/util/spring_boot_utils.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/start_script.rb b/lib/java_buildpack/util/start_script.rb index c5867ccc01..3c532ef9a1 100644 --- a/lib/java_buildpack/util/start_script.rb +++ b/lib/java_buildpack/util/start_script.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/to_b.rb b/lib/java_buildpack/util/to_b.rb index c7349d4881..76e36b259e 100644 --- a/lib/java_buildpack/util/to_b.rb +++ b/lib/java_buildpack/util/to_b.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index 57bcdd55d8..5a98ff1347 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 90641f4028..415411fa28 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/package.rb b/rakelib/package.rb index f449cc8d7d..3470d0d7a1 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/package_task.rb b/rakelib/package_task.rb index 1d7b7ae43f..82c31a059d 100644 --- a/rakelib/package_task.rb +++ b/rakelib/package_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/stage_buildpack_task.rb b/rakelib/stage_buildpack_task.rb index 2a13f58ca9..0a67e7e4f8 100644 --- a/rakelib/stage_buildpack_task.rb +++ b/rakelib/stage_buildpack_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 6e0aa83b88..1c487109be 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2019 the original author or authors. +# Copyright 2013-2020 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/resources/azure_application_insights_agent/AI-Agent.xml b/resources/azure_application_insights_agent/AI-Agent.xml index 53355d659c..7e1ff431c0 100644 --- a/resources/azure_application_insights_agent/AI-Agent.xml +++ b/resources/azure_application_insights_agent/AI-Agent.xml @@ -1,6 +1,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.singularity.ee.agent.appagent.kernel.DynamicServiceManager + + + + + + + + + + BCIEngine,TransactionMonitoringService,SnapshotService + + + + + + + + BCIEngine + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BCIEngine + + + + + + + + + + + + + + + + + + + + + + + + + + + + BCIEngine,SnapshotService + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JMXService + + + BCIEngine + + + + + + + + + + + + + + + + + + + + + + + + + + BCIEngine + + + + + + + + + + + + + + + + + + + + + + + BCIEngine + + + + + TransactionMonitoringService + + + + + + + + + + + + + + diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 19567dbf64..03e83d2512 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -165,6 +165,18 @@ component.compile end end + + context do + + let(:environment) { { 'APPD_CONF_DIR' => 'BOOT-INF/classes/appdynamics/conf' } } + + it 'sets APPD_CONF_DIR env var to copy config files from app dir', + app_fixture: 'framework_app_dynamics_agent', + cache_fixture: 'stub-app-dynamics-agent.zip' do + + component.compile + end + end end end end From f558fcc43ab131b263c5774bca891a95b7eaec63 Mon Sep 17 00:00:00 2001 From: vchrisb Date: Wed, 25 Nov 2020 19:00:23 +0100 Subject: [PATCH 595/812] fix file path concatenation --- lib/java_buildpack/framework/app_dynamics_agent.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 6197b3fcba..a5b248ec29 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -203,7 +203,7 @@ def override_default_config_local app_conf_dir = @application.environment['APPD_CONF_DIR'] @logger.info { "Copy override configuration files from #{app_conf_dir}" } CONFIG_FILES.each do |conf_file| - conf_file_path = @application.root + app_conf_dir + '/' + conf_file + conf_file_path = @application.root + app_conf_dir + conf_file next unless File.file?(conf_file_path) From 73c2dfffeda36b3df4258fdce8d618bd93e02019 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 15 Dec 2020 13:10:27 -0500 Subject: [PATCH 596/812] Update geode-store version --- config/tomcat.yml | 4 ++-- .../container/tomcat/tomcat_geode_store.rb | 24 ++----------------- ...ainer_tomcat_geode_store_context_after.xml | 2 +- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index bd31372868..ccab76de31 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -40,5 +40,5 @@ redis_store: timeout: 2000 connection_pool_size: 2 geode_store: - version: 0.+ - repository_root: https://repo.spring.io/ext-release-local/geode-store + version: 1.13.+ + repository_root: https://tgf4vms-session-state-buildpack-dependencies.s3-us-west-2.amazonaws.com diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 406bcc384d..31ddfc84c2 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -63,7 +63,7 @@ def supports? KEY_LOCATORS = 'locators' KEY_USERS = 'users' - SESSION_MANAGER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.Tomcat8DeltaSessionManager' + SESSION_MANAGER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.Tomcat9DeltaSessionManager' REGION_ATTRIBUTES_ID = 'PARTITION_REDUNDANT_HEAP_LRU' CACHE_CLIENT_LISTENER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.ClientServerCacheLifecycleListener' @@ -71,16 +71,10 @@ def supports? SCHEMA_INSTANCE_URL = 'http://www.w3.org/2001/XMLSchema-instance' SCHEMA_LOCATION = 'http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd' LOCATOR_REGEXP = Regexp.new('([^\\[]+)\\[([^\\]]+)\\]').freeze - FUNCTION_SERVICE_CLASS_NAMES = [ - 'org.apache.geode.modules.util.CreateRegionFunction', - 'org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction', - 'org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction', - 'org.apache.geode.modules.util.RegionSizeFunction' - ].freeze private_constant :FILTER, :KEY_LOCATORS, :KEY_USERS, :SESSION_MANAGER_CLASS_NAME, :REGION_ATTRIBUTES_ID, :CACHE_CLIENT_LISTENER_CLASS_NAME, :SCHEMA_URL, :SCHEMA_INSTANCE_URL, :SCHEMA_LOCATION, - :LOCATOR_REGEXP, :FUNCTION_SERVICE_CLASS_NAMES + :LOCATOR_REGEXP def cluster_operator?(user) user['username'] == 'cluster_operator' || user['roles'] && (user['roles'].include? 'cluster_operator') @@ -94,20 +88,6 @@ def add_client_cache(document) 'version' => '1.0' add_pool client_cache - add_function_service client_cache - end - - def add_functions(function_service) - FUNCTION_SERVICE_CLASS_NAMES.each do |function_class_name| - function = function_service.add_element 'function' - class_name = function.add_element 'class-name' - class_name.add_text(function_class_name) - end - end - - def add_function_service(client_cache) - function_service = client_cache.add_element 'function-service' - add_functions function_service end def add_listener(server) diff --git a/spec/fixtures/container_tomcat_geode_store_context_after.xml b/spec/fixtures/container_tomcat_geode_store_context_after.xml index ea4a8b558e..8eb45842b4 100644 --- a/spec/fixtures/container_tomcat_geode_store_context_after.xml +++ b/spec/fixtures/container_tomcat_geode_store_context_after.xml @@ -16,5 +16,5 @@ ~ limitations under the License. --> - + From b5365792bac6a37401cd2197ceb3f16f0f50d784 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 15 Dec 2020 14:14:46 -0500 Subject: [PATCH 597/812] Fix expected client-cache.xml for geode-store --- ...ainer_tomcat_geode_store_cache_client_after.xml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/spec/fixtures/container_tomcat_geode_store_cache_client_after.xml b/spec/fixtures/container_tomcat_geode_store_cache_client_after.xml index b68c118145..41e41f1612 100644 --- a/spec/fixtures/container_tomcat_geode_store_cache_client_after.xml +++ b/spec/fixtures/container_tomcat_geode_store_cache_client_after.xml @@ -4,18 +4,4 @@ - - - org.apache.geode.modules.util.CreateRegionFunction - - - org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction - - - org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction - - - org.apache.geode.modules.util.RegionSizeFunction - - From 776cd74d7d6d8eebfcd57e1156063c39f49c14af Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 11 Jan 2021 13:56:26 -0500 Subject: [PATCH 598/812] Update geode store repo root --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index ccab76de31..5e47bee503 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -41,4 +41,4 @@ redis_store: connection_pool_size: 2 geode_store: version: 1.13.+ - repository_root: https://tgf4vms-session-state-buildpack-dependencies.s3-us-west-2.amazonaws.com + repository_root: https://apache-geode-session-state-buildpack-dependencies.s3-us-west-2.amazonaws.com From 2b82a918b164181cd5c622f852bac4eb95a56fc8 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 11 Jan 2021 14:25:46 -0500 Subject: [PATCH 599/812] Update geode store repo root --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index 5e47bee503..fee2c18492 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -41,4 +41,4 @@ redis_store: connection_pool_size: 2 geode_store: version: 1.13.+ - repository_root: https://apache-geode-session-state-buildpack-dependencies.s3-us-west-2.amazonaws.com + repository_root: https://apache-geode-tomcat-session-buildpack-dependencies.s3-us-west-2.amazonaws.com From eb308ce0b6466c932653016e869e197c0103beed Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 19 Jan 2021 17:10:37 -0500 Subject: [PATCH 600/812] Update geode store repo root --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index fee2c18492..5c9aefc730 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -41,4 +41,4 @@ redis_store: connection_pool_size: 2 geode_store: version: 1.13.+ - repository_root: https://apache-geode-tomcat-session-buildpack-dependencies.s3-us-west-2.amazonaws.com + repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 36bb71b383d2c575444926b4c361ceb88841ddc6 Mon Sep 17 00:00:00 2001 From: vchrisb Date: Fri, 22 Jan 2021 14:00:12 +0100 Subject: [PATCH 601/812] enhanced error handling and test cases * raising RuntimeError if `APPD_CONF_DIR` is provided but directory does not exist * added version directory `stub-app-dynamics-agent.zip` * test if config file gets succesfully copied * test if error is raised when provided directory does not exist --- .../framework/app_dynamics_agent.rb | 7 +++++-- .../appdynamics/conf/app-agent-config.xml | 1 + spec/fixtures/stub-app-dynamics-agent.zip | Bin 176 -> 506 bytes .../framework/app_dynamics_agent_spec.rb | 13 +++++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 3da2871af8..5a676e827a 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -201,10 +201,13 @@ def override_default_config_remote def override_default_config_local return unless @application.environment['APPD_CONF_DIR'] - app_conf_dir = @application.environment['APPD_CONF_DIR'] + app_conf_dir = @application.root + @application.environment['APPD_CONF_DIR'] + + raise "AppDynamics configuration source dir #{app_conf_dir} does not exist" unless Dir.exist?(app_conf_dir) + @logger.info { "Copy override configuration files from #{app_conf_dir}" } CONFIG_FILES.each do |conf_file| - conf_file_path = @application.root + app_conf_dir + conf_file + conf_file_path = app_conf_dir + conf_file next unless File.file?(conf_file_path) diff --git a/spec/fixtures/framework_app_dynamics_agent/BOOT-INF/classes/appdynamics/conf/app-agent-config.xml b/spec/fixtures/framework_app_dynamics_agent/BOOT-INF/classes/appdynamics/conf/app-agent-config.xml index b09a260565..b934fa90f3 100644 --- a/spec/fixtures/framework_app_dynamics_agent/BOOT-INF/classes/appdynamics/conf/app-agent-config.xml +++ b/spec/fixtures/framework_app_dynamics_agent/BOOT-INF/classes/appdynamics/conf/app-agent-config.xml @@ -1,3 +1,4 @@ + diff --git a/spec/fixtures/stub-app-dynamics-agent.zip b/spec/fixtures/stub-app-dynamics-agent.zip index a973e1e9dd34b1831c8b53880d0bea057aaee9a7..5e879a4c58d9aa90349897e1c653b43b94375cb3 100644 GIT binary patch literal 506 zcmWIWW@h1H0D*PY)y`lBl;CBMVaQ4>OH52p%`4H%N-PQu;bdSw!8k1lgi9;985mi< zGcqu+hyXPNz>PVTWEO;Mi~!J>veY6YLp?)113hCyQwt+~ut_;vxe^M27^g|$XeNnb zF)2AeFAZYcv@Ki-AdF!gBa<96E+0z3UAm+Z#6WBQgCB oG!^7`Jf>p$9NE-~SWJb61JG!!VZh1;@*Oh}vH)Z30f@r@0F}B?jQ{`u delta 64 zcmeyxyn&G?z?+$civa}I6;I?bV*EO}kx_&R$bM%d|CNz}fkgx;72wUv22#QZguy`C I9mHV(0Oi^X!vFvP diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 0856825ee4..f89795ec06 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -199,6 +199,19 @@ cache_fixture: 'stub-app-dynamics-agent.zip' do component.compile + expect(File.read(sandbox + "ver21.1.0.31582/conf/app-agent-config.xml")).to include "sourced by APPD_CONF_DIR" + end + end + + context do + + let(:environment) { { 'APPD_CONF_DIR' => 'BOOT-INF/classes/appdynamics/conf-false' } } + + it 'sets APPD_CONF_DIR env var to copy config files from incorrect app dir', + app_fixture: 'framework_app_dynamics_agent', + cache_fixture: 'stub-app-dynamics-agent.zip' do + + expect{component.compile}.to raise_error(RuntimeError, /AppDynamics configuration source dir/) end end end From 36f915773bba22345a9a4e96ee5e08f3644f5de7 Mon Sep 17 00:00:00 2001 From: vchrisb Date: Fri, 22 Jan 2021 14:16:26 +0100 Subject: [PATCH 602/812] RuboCop fixes --- spec/java_buildpack/framework/app_dynamics_agent_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index f89795ec06..9927e80ca9 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -199,10 +199,10 @@ cache_fixture: 'stub-app-dynamics-agent.zip' do component.compile - expect(File.read(sandbox + "ver21.1.0.31582/conf/app-agent-config.xml")).to include "sourced by APPD_CONF_DIR" + expect(File.read(sandbox + 'ver21.1.0.31582/conf/app-agent-config.xml')).to include 'sourced by APPD_CONF_DIR' end end - + context do let(:environment) { { 'APPD_CONF_DIR' => 'BOOT-INF/classes/appdynamics/conf-false' } } @@ -211,7 +211,7 @@ app_fixture: 'framework_app_dynamics_agent', cache_fixture: 'stub-app-dynamics-agent.zip' do - expect{component.compile}.to raise_error(RuntimeError, /AppDynamics configuration source dir/) + expect { component.compile }.to raise_error(RuntimeError, /AppDynamics configuration source dir/) end end end From 92cbc4dc6b0c698448b5e8e011a87c8b0857c0f1 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 22 Jan 2021 12:36:52 -0500 Subject: [PATCH 603/812] Update product name in container-tomcat.md --- docs/container-tomcat.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index 246f8c7047..b9836daef9 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -92,8 +92,8 @@ By default, the Tomcat instance is configured to store all Sessions and their da ### Redis To enable Redis-based session replication, simply bind a Redis service containing a name, label, or tag that has `session-replication` as a substring. -### Pivotal Cloud Cache -To enable session state caching on 'Pivotal Cloud Cache', bind to a 'Pivotal Cloud Cache' service instance who's name either ends in `-session-replication` or is tagged with `session-replication`. +### Tanzu GemFire for VMs +To enable session state caching on 'Tanzu GemFire for VMs', bind to a 'Tanzu GemFire' service instance whose name either ends in `-session-replication` or is tagged with `session-replication`. Service instances can be created with a tag: From 448adeef2bd3489a19c2a859b19af09592266790 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 22 Jan 2021 12:39:35 -0500 Subject: [PATCH 604/812] Remove single quotes from product name --- docs/container-tomcat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index b9836daef9..afefcb3a6f 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -93,7 +93,7 @@ By default, the Tomcat instance is configured to store all Sessions and their da To enable Redis-based session replication, simply bind a Redis service containing a name, label, or tag that has `session-replication` as a substring. ### Tanzu GemFire for VMs -To enable session state caching on 'Tanzu GemFire for VMs', bind to a 'Tanzu GemFire' service instance whose name either ends in `-session-replication` or is tagged with `session-replication`. +To enable session state caching on Tanzu GemFire for VMs, bind to a Tanzu GemFire service instance whose name either ends in `-session-replication` or is tagged with `session-replication`. Service instances can be created with a tag: From 19d1963ae1603af5c34bf403353227e8850385fa Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Mon, 25 Jan 2021 09:19:40 -0500 Subject: [PATCH 605/812] Fix cached jre for java 15 Signed-off-by: Emily Casey --- rakelib/dependency_cache_task.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index d5b25e9345..2a497e2390 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -132,7 +132,7 @@ def configurations(component_id, configuration, sub_component_id = nil) if component_id == 'open_jdk_jre' && sub_component_id == 'jre' c1 = configuration.clone - c1['version'] = '14.+' + c1['version'] = '15.+' configurations << c1 end From 8d022184cf044ba2e0c227492ad5b30053e8537a Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Mon, 25 Jan 2021 17:02:05 -0500 Subject: [PATCH 606/812] Don't sign release commit Signed-off-by: Emily Casey --- ci/create-release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/create-release.sh b/ci/create-release.sh index d3af657e41..99a62cbdc8 100755 --- a/ci/create-release.sh +++ b/ci/create-release.sh @@ -17,5 +17,5 @@ bundle exec rake versions:markdown versions:json git add . git commit --message "v$RELEASE Release" -git tag -s v$RELEASE -m "v$RELEASE" +git tag -m "v$RELEASE" git reset --hard HEAD^1 From ebf9f0574ca02417b9457652edb439ec1944a34e Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Mon, 25 Jan 2021 17:24:50 -0500 Subject: [PATCH 607/812] fix create-release.sh Signed-off-by: Emily Casey --- ci/create-release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/create-release.sh b/ci/create-release.sh index 99a62cbdc8..0ab439ffde 100755 --- a/ci/create-release.sh +++ b/ci/create-release.sh @@ -17,5 +17,5 @@ bundle exec rake versions:markdown versions:json git add . git commit --message "v$RELEASE Release" -git tag -m "v$RELEASE" +git tag "v$RELEASE" git reset --hard HEAD^1 From 7e780b1900862e09906d2957a5d1c4e554e28f57 Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 27 Jan 2021 12:59:35 -0500 Subject: [PATCH 608/812] Update geode store version --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index 5c9aefc730..e7def06a9e 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -40,5 +40,5 @@ redis_store: timeout: 2000 connection_pool_size: 2 geode_store: - version: 1.13.+ + version: 1.11.+ repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 091e00d8b4e985b3f014466d6734564d7f7afaf4 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 27 Jan 2021 16:02:43 -0500 Subject: [PATCH 609/812] Added basic auth support when using APPD_CONF_HTTP_URL to fetch configuration from a remote server. --- .../framework/app_dynamics_agent.rb | 6 ++++- .../framework/app_dynamics_agent_spec.rb | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 5a676e827a..ed763db979 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -148,7 +148,11 @@ def check_if_resource_exists(resource_uri, conf_file) begin opts = { use_ssl: true } if resource_uri.scheme == 'https' response = Net::HTTP.start(resource_uri.host, resource_uri.port, opts) do |http| - http.request_head(resource_uri) + req = Net::HTTP::Head.new(resource_uri) + if resource_uri.user != '' || resource_uri.password != '' + req.basic_auth(resource_uri.user, resource_uri.password) + end + http.request(req) end rescue StandardError => e @logger.error { "Request failure: #{e.message}" } diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index 9927e80ca9..ac981959a6 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -190,6 +190,29 @@ end end + context do + let(:environment) { { 'APPD_CONF_HTTP_URL' => 'https://user:pass@foo.com' } } + + it 'sets APPD_CONF_HTTP_URL env var to download config files over HTTPS with Basic Auth', + cache_fixture: 'stub-app-dynamics-agent.zip' do + + config_files = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml + service-endpoint.xml transactions.xml custom-interceptors.xml + custom-activity-correlation.xml] + + config_files.each do |file| + allow(application_cache).to receive(:get) + .with("https://user:pass@foo.com/java/#{file}") + allow(Net::HTTP).to receive(:start).with('foo.com', 443, use_ssl: true).and_call_original + stub_request(:head, "https://foo.com/java/#{file}") + .with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby', + 'Authorization' => 'Basic dXNlcjpwYXNz' }) + .to_return(status: 200, body: '', headers: {}) + end + component.compile + end + end + context do let(:environment) { { 'APPD_CONF_DIR' => 'BOOT-INF/classes/appdynamics/conf' } } From 8232473889d5a5bb8badc69808cc05ef20fcea73 Mon Sep 17 00:00:00 2001 From: Gunter Haug Date: Thu, 28 Jan 2021 10:39:32 +0100 Subject: [PATCH 610/812] Improve packaging of offline version. Allow for additional components in the cache --- README.md | 4 +++- rakelib/dependency_cache_task.rb | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index beb6b3cc94..f1a2f68a74 100644 --- a/README.md +++ b/README.md @@ -158,9 +158,11 @@ The offline package is a version of the buildpack designed to run without access To pin the version of dependencies used by the buildpack to the ones currently resolvable use the `PINNED=true` argument. This will update the [`config/` directory][] to contain exact version of each dependency instead of version ranges. +Only packages referenced in the [`config/components.yml` file][] will be cached. Additional packages may be added using the `ADD_TO_CACHE` argument. It has to be set to the name of a `.yml` file in the [`config/` directory][]). Multiple file names may be separated by colons. This is useful to add additional JREs. + ```bash $ bundle install -$ bundle exec rake clean package OFFLINE=true PINNED=true +$ bundle exec rake clean package OFFLINE=true PINNED=true ADD_TO_CACHE=sap_machine_jre ... Creating build/java-buildpack-offline-cfd6b17.zip ``` diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 2a497e2390..03ae17b3b5 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -109,7 +109,10 @@ def cache_task(uri) end def component_ids - configuration('components').values.flatten.map { |component| component.split('::').last.snake_case } + conf = configuration('components').values.flatten.map { |component| component.split('::').last.snake_case } + offline_cache = ENV['ADD_TO_CACHE'].split(':') + (conf << offline_cache).flatten!.uniq! + conf end def configuration(id) From 1a0299e1857aa941cd6d384841db66373414b270 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 29 Jan 2021 17:51:20 -0500 Subject: [PATCH 611/812] Add security credentils for geode store to gemfire.properties file --- lib/java_buildpack/container/tomcat/tomcat_geode_store.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 31ddfc84c2..d91b47aecc 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -44,6 +44,9 @@ def release credentials = @application.services.find_service(FILTER, KEY_LOCATORS, KEY_USERS)['credentials'] user = credentials[KEY_USERS].find { |u| cluster_operator?(u) } + File.open(@droplet.root + "gemfire.properties", "w") {|f| f.write("security-username=" + user['username'] + + "\nsecurity-password=" + user['password']) } + @droplet.java_opts.add_system_property 'gemfire.security-username', user['username'] @droplet.java_opts.add_system_property 'gemfire.security-password', user['password'] @droplet.java_opts.add_system_property 'gemfire.security-client-auth-init', From 295f71f26c2c4ef4db60f31d5e56060ba1208fc1 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 29 Jan 2021 17:56:34 -0500 Subject: [PATCH 612/812] Remove credentials from JAVA_OPTS --- lib/java_buildpack/container/tomcat/tomcat_geode_store.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index d91b47aecc..2d4aefdb65 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -47,8 +47,6 @@ def release File.open(@droplet.root + "gemfire.properties", "w") {|f| f.write("security-username=" + user['username'] + "\nsecurity-password=" + user['password']) } - @droplet.java_opts.add_system_property 'gemfire.security-username', user['username'] - @droplet.java_opts.add_system_property 'gemfire.security-password', user['password'] @droplet.java_opts.add_system_property 'gemfire.security-client-auth-init', 'io.pivotal.cloudcache.ClientAuthInitialize.create' end From 433ecc43f382d1f5852b57e045143c4c9f86b68f Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 1 Feb 2021 16:52:40 -0500 Subject: [PATCH 613/812] Updated tests --- .../container/tomcat/tomcat_geode_store.rb | 5 +++-- spec/fixtures/expected_gemfire_properties | 2 ++ .../expected_gemfire_properties_without_role | 2 ++ .../container/tomcat/tomcat_geode_store_spec.rb | 12 ++++++++---- 4 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 spec/fixtures/expected_gemfire_properties create mode 100644 spec/fixtures/expected_gemfire_properties_without_role diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 2d4aefdb65..d445bb5e00 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -44,8 +44,9 @@ def release credentials = @application.services.find_service(FILTER, KEY_LOCATORS, KEY_USERS)['credentials'] user = credentials[KEY_USERS].find { |u| cluster_operator?(u) } - File.open(@droplet.root + "gemfire.properties", "w") {|f| f.write("security-username=" + user['username'] + - "\nsecurity-password=" + user['password']) } + File.open(@droplet.root + 'gemfire.properties', 'w') do |f| + f.write('security-username=' + user['username'] + "\nsecurity-password=" + user['password']) + end @droplet.java_opts.add_system_property 'gemfire.security-client-auth-init', 'io.pivotal.cloudcache.ClientAuthInitialize.create' diff --git a/spec/fixtures/expected_gemfire_properties b/spec/fixtures/expected_gemfire_properties new file mode 100644 index 0000000000..b41259c569 --- /dev/null +++ b/spec/fixtures/expected_gemfire_properties @@ -0,0 +1,2 @@ +security-username=some-username +security-password=some-password \ No newline at end of file diff --git a/spec/fixtures/expected_gemfire_properties_without_role b/spec/fixtures/expected_gemfire_properties_without_role new file mode 100644 index 0000000000..6ea9a92335 --- /dev/null +++ b/spec/fixtures/expected_gemfire_properties_without_role @@ -0,0 +1,2 @@ +security-username=cluster_operator +security-password=some-password \ No newline at end of file diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index 3beea3622e..ec40d8d33d 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -107,8 +107,10 @@ expect(java_opts).to include( '-Dgemfire.security-client-auth-init=io.pivotal.cloudcache.ClientAuthInitialize.create' ) - expect(java_opts).to include('-Dgemfire.security-username=some-username') - expect(java_opts).to include('-Dgemfire.security-password=some-password') + + expect(app_dir + 'gemfire.properties').to exist + expect((app_dir + 'gemfire.properties').read) + .to eq(Pathname.new('spec/fixtures/expected_gemfire_properties').read) end end @@ -139,8 +141,10 @@ expect(java_opts).to include( '-Dgemfire.security-client-auth-init=io.pivotal.cloudcache.ClientAuthInitialize.create' ) - expect(java_opts).to include('-Dgemfire.security-username=cluster_operator') - expect(java_opts).to include('-Dgemfire.security-password=some-password') + + expect(app_dir + 'gemfire.properties').to exist + expect((app_dir + 'gemfire.properties').read) + .to eq(Pathname.new('spec/fixtures/expected_gemfire_properties_without_role').read) end end end From cf9f88762fd3ff85bfd3e0b13ee38ee3e8cbe0f7 Mon Sep 17 00:00:00 2001 From: Ben Ross Date: Thu, 11 Feb 2021 10:39:20 -0800 Subject: [PATCH 614/812] Removed unnecessary gemfire.properties --- .../container/tomcat/tomcat_geode_store.rb | 7 ---- spec/fixtures/expected_gemfire_properties | 2 - .../expected_gemfire_properties_without_role | 2 - .../tomcat/tomcat_geode_store_spec.rb | 38 ------------------- 4 files changed, 49 deletions(-) delete mode 100644 spec/fixtures/expected_gemfire_properties delete mode 100644 spec/fixtures/expected_gemfire_properties_without_role diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index d445bb5e00..80f30f4c3c 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -41,13 +41,6 @@ def compile def release return unless supports? - credentials = @application.services.find_service(FILTER, KEY_LOCATORS, KEY_USERS)['credentials'] - user = credentials[KEY_USERS].find { |u| cluster_operator?(u) } - - File.open(@droplet.root + 'gemfire.properties', 'w') do |f| - f.write('security-username=' + user['username'] + "\nsecurity-password=" + user['password']) - end - @droplet.java_opts.add_system_property 'gemfire.security-client-auth-init', 'io.pivotal.cloudcache.ClientAuthInitialize.create' end diff --git a/spec/fixtures/expected_gemfire_properties b/spec/fixtures/expected_gemfire_properties deleted file mode 100644 index b41259c569..0000000000 --- a/spec/fixtures/expected_gemfire_properties +++ /dev/null @@ -1,2 +0,0 @@ -security-username=some-username -security-password=some-password \ No newline at end of file diff --git a/spec/fixtures/expected_gemfire_properties_without_role b/spec/fixtures/expected_gemfire_properties_without_role deleted file mode 100644 index 6ea9a92335..0000000000 --- a/spec/fixtures/expected_gemfire_properties_without_role +++ /dev/null @@ -1,2 +0,0 @@ -security-username=cluster_operator -security-password=some-password \ No newline at end of file diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index ec40d8d33d..9ddd46b1bd 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -107,44 +107,6 @@ expect(java_opts).to include( '-Dgemfire.security-client-auth-init=io.pivotal.cloudcache.ClientAuthInitialize.create' ) - - expect(app_dir + 'gemfire.properties').to exist - expect((app_dir + 'gemfire.properties').read) - .to eq(Pathname.new('spec/fixtures/expected_gemfire_properties').read) - end - end - - context 'when there is session replication service and service credentials do not include roles' do - before do - allow(services).to receive(:one_service?).with(/session-replication/, 'locators', 'users') - .and_return(true) - allow(services).to receive(:find_service).and_return( - 'credentials' => { - 'locators' => ['some-locator[some-port]', 'some-other-locator[some-other-port]'], - 'users' => - [ - { - 'password' => 'some-password', - 'username' => 'cluster_operator' - } - ] - } - ) - end - - it 'assumes usernames represent roles and passes security properties to the release', - app_fixture: 'container_tomcat_geode_store', - cache_fixture: 'stub-geode-store.tar' do - - component.release - - expect(java_opts).to include( - '-Dgemfire.security-client-auth-init=io.pivotal.cloudcache.ClientAuthInitialize.create' - ) - - expect(app_dir + 'gemfire.properties').to exist - expect((app_dir + 'gemfire.properties').read) - .to eq(Pathname.new('spec/fixtures/expected_gemfire_properties_without_role').read) end end end From d0707a28adf93b3f851775322487198e9a8eecca Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 16 Feb 2021 12:27:20 -0500 Subject: [PATCH 615/812] Removes unused function --- lib/java_buildpack/container/tomcat/tomcat_geode_store.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 80f30f4c3c..58279aaefc 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -71,10 +71,6 @@ def supports? :CACHE_CLIENT_LISTENER_CLASS_NAME, :SCHEMA_URL, :SCHEMA_INSTANCE_URL, :SCHEMA_LOCATION, :LOCATOR_REGEXP - def cluster_operator?(user) - user['username'] == 'cluster_operator' || user['roles'] && (user['roles'].include? 'cluster_operator') - end - def add_client_cache(document) client_cache = document.add_element 'client-cache', 'xmlns' => SCHEMA_URL, From 7806f8daf6ceced6efc60ad3d13442851f1c02e8 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 18 Feb 2021 11:21:26 -0500 Subject: [PATCH 616/812] Update geode store version --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index e7def06a9e..53bc9f51d1 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -40,5 +40,5 @@ redis_store: timeout: 2000 connection_pool_size: 2 geode_store: - version: 1.11.+ + version: 1.11.0 repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 1e196a6185eacf874ca9592eaab231246b5f6410 Mon Sep 17 00:00:00 2001 From: Jason Zhen Date: Thu, 25 Feb 2021 09:46:36 -0800 Subject: [PATCH 617/812] updated to pull the latest Instroscope Agent. --- config/introscope_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index 781cd17aaf..5a9095a913 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -15,6 +15,6 @@ # Configuration for the CA Wily framework --- -version: 20.+ +version: + repository_root: https://ca.bintray.com/apm-agents default_agent_name: $(jq -r -n "$VCAP_APPLICATION | .application_name") From 44fbdf5a72aecf8498f2e4914b27cb6c4b2f5a61 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 8 Mar 2021 13:13:14 -0500 Subject: [PATCH 618/812] Edits comment in tomcat_geode_store --- lib/java_buildpack/container/tomcat/tomcat_geode_store.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 31ddfc84c2..ad79c5cedc 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -23,7 +23,7 @@ module JavaBuildpack module Container - # Encapsulates the detect, compile, and release functionality for Tomcat Redis support. + # Encapsulates the detect, compile, and release functionality for Tomcat Tanzu GemFire for VMs support. class TomcatGeodeStore < JavaBuildpack::Component::VersionedDependencyComponent include JavaBuildpack::Container From 0423175dfc01ed415b1858f8b1d5dfc40136e5b5 Mon Sep 17 00:00:00 2001 From: Ben Ross Date: Mon, 15 Mar 2021 13:37:55 -0700 Subject: [PATCH 619/812] Added documentation about geode_store values --- docs/container-tomcat.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/container-tomcat.md b/docs/container-tomcat.md index afefcb3a6f..2927795cd9 100644 --- a/docs/container-tomcat.md +++ b/docs/container-tomcat.md @@ -25,6 +25,8 @@ The container can be configured by modifying the [`config/tomcat.yml`][] file in | `access_logging_support.repository_root` | The URL of the Tomcat Access Logging Support repository index ([details][repositories]). | `access_logging_support.version` | The version of Tomcat Access Logging Support to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/tomcat-access-logging-support/index.yml). | `access_logging_support.access_logging` | Set to `enabled` to turn on the access logging support. Default is `disabled`. +| `geode_store.repository_root` | The URL of the Geode Store repository index ([details][repositories]). +| `geode_store.version` | The version of Geode Store to use. Candidate versions can be found in [this listing](https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com/index.yml). | `lifecycle_support.repository_root` | The URL of the Tomcat Lifecycle Support repository index ([details][repositories]). | `lifecycle_support.version` | The version of Tomcat Lifecycle Support to use. Candidate versions can be found in [this listing](http://download.pivotal.io.s3.amazonaws.com/tomcat-lifecycle-support/index.yml). | `logging_support.repository_root` | The URL of the Tomcat Logging Support repository index ([details][repositories]). From 09b1672ad23b7b53f466949c97e1328b79cca594 Mon Sep 17 00:00:00 2001 From: Gunter Haug <42777423+ghaug@users.noreply.github.com> Date: Tue, 16 Mar 2021 12:13:16 +0100 Subject: [PATCH 620/812] Update dependency_cache_task.rb --- rakelib/dependency_cache_task.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 03ae17b3b5..1625ea2c28 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -110,8 +110,11 @@ def cache_task(uri) def component_ids conf = configuration('components').values.flatten.map { |component| component.split('::').last.snake_case } - offline_cache = ENV['ADD_TO_CACHE'].split(':') - (conf << offline_cache).flatten!.uniq! + offline_cache = ENV['ADD_TO_CACHE'] + if !offline_cache.nil? + offline_cache = offline_cache.split(':') + (conf << offline_cache).flatten!.uniq! + end conf end From f93725d4148092367c71015baa8e55ef5ba91e10 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 16 Mar 2021 10:26:50 -0400 Subject: [PATCH 621/812] Add comment explaining geode store version compatibility --- config/tomcat.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/tomcat.yml b/config/tomcat.yml index 53bc9f51d1..d66c7d1174 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -40,5 +40,7 @@ redis_store: timeout: 2000 connection_pool_size: 2 geode_store: + # The version of Geode Store must be less than or equal to the Geode server version to ensure compatibility. + # The Geode Store version is pinned to 1.11.0 to match the oldest supported version of Tanzu Gemfire for VMs. version: 1.11.0 repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 3aaefb6cba56a5b37197e62e3a0742dfbdd51209 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 16 Mar 2021 17:35:39 -0400 Subject: [PATCH 622/812] Update comments based on feedback from PMs --- config/tomcat.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index d66c7d1174..96db7f2b85 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -40,7 +40,7 @@ redis_store: timeout: 2000 connection_pool_size: 2 geode_store: - # The version of Geode Store must be less than or equal to the Geode server version to ensure compatibility. - # The Geode Store version is pinned to 1.11.0 to match the oldest supported version of Tanzu Gemfire for VMs. + # The version of Geode Store must be less than or equal to your Tanzu Gemfire for VMs version to ensure compatibility. + # The Geode Store version is pinned to 1.11.0 to be compatible with the most commonly used versions of Tanzu Gemfire for VMs. version: 1.11.0 repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 411241dd4708acf29025d6441773312a58ddf49f Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 2 Feb 2021 12:09:59 -0500 Subject: [PATCH 623/812] Detect Geode Tomcat module version --- config/tomcat.yml | 2 +- lib/java_buildpack/container/tomcat.rb | 8 ++- .../container/tomcat/tomcat_geode_store.rb | 43 +++++++++++-- ...mcat_version_geode_store_context_after.xml | 20 ++++++ ...iner_tomcat8_geode_store_context_after.xml | 20 ++++++ ...ainer_tomcat_geode_store_context_after.xml | 2 +- .../stub-geode-store-no-geode-tomcat.tar | Bin 0 -> 10240 bytes .../stub-geode-store-no-tomcat-version.tar | Bin 0 -> 10240 bytes .../stub-geode-store-tomcat-multi-version.tar | Bin 0 -> 61440 bytes spec/fixtures/stub-geode-store-tomcat8.tar | Bin 0 -> 30720 bytes spec/fixtures/stub-geode-store.tar | Bin 444 -> 10240 bytes .../tomcat/tomcat_geode_store_spec.rb | 58 ++++++++++++++++-- spec/java_buildpack/container/tomcat_spec.rb | 14 +++-- 13 files changed, 148 insertions(+), 19 deletions(-) create mode 100644 spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml create mode 100644 spec/fixtures/container_tomcat8_geode_store_context_after.xml create mode 100644 spec/fixtures/stub-geode-store-no-geode-tomcat.tar create mode 100644 spec/fixtures/stub-geode-store-no-tomcat-version.tar create mode 100644 spec/fixtures/stub-geode-store-tomcat-multi-version.tar create mode 100644 spec/fixtures/stub-geode-store-tomcat8.tar diff --git a/config/tomcat.yml b/config/tomcat.yml index 96db7f2b85..909080859e 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -1,5 +1,5 @@ # Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. +# Copyright 2013-2021 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 43a787a818..8aa40721ee 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. +# Copyright 2013-2021 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -52,8 +52,12 @@ def command # (see JavaBuildpack::Component::ModularComponent#sub_components) def sub_components(context) + instance = TomcatInstance.new(sub_configuration_context(context, 'tomcat')) + # pass Tomcat major version to geode_store so we can verify compatibility. + @configuration['geode_store']['tomcat_version'] = instance.instance_variable_get(:@version)[0] + components = [ - TomcatInstance.new(sub_configuration_context(context, 'tomcat')), + instance, TomcatAccessLoggingSupport.new(sub_configuration_context(context, 'access_logging_support')), TomcatGeodeStore.new(sub_configuration_context(context, 'geode_store')), TomcatInsightSupport.new(context), diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index d7ba127e59..765e9e7007 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. +# Copyright 2013-2021 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ def compile return unless supports? download_tar(false, tomcat_lib, tar_name) + detect_geode_tomcat_version mutate_context mutate_server create_cache_client_xml @@ -58,7 +59,6 @@ def supports? KEY_LOCATORS = 'locators' KEY_USERS = 'users' - SESSION_MANAGER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.Tomcat9DeltaSessionManager' REGION_ATTRIBUTES_ID = 'PARTITION_REDUNDANT_HEAP_LRU' CACHE_CLIENT_LISTENER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.ClientServerCacheLifecycleListener' @@ -67,7 +67,7 @@ def supports? SCHEMA_LOCATION = 'http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd' LOCATOR_REGEXP = Regexp.new('([^\\[]+)\\[([^\\]]+)\\]').freeze - private_constant :FILTER, :KEY_LOCATORS, :KEY_USERS, :SESSION_MANAGER_CLASS_NAME, :REGION_ATTRIBUTES_ID, + private_constant :FILTER, :KEY_LOCATORS, :KEY_USERS, :REGION_ATTRIBUTES_ID, :CACHE_CLIENT_LISTENER_CLASS_NAME, :SCHEMA_URL, :SCHEMA_INSTANCE_URL, :SCHEMA_LOCATION, :LOCATOR_REGEXP @@ -98,7 +98,7 @@ def add_locators(pool) def add_manager(context) context.add_element 'Manager', - 'className' => SESSION_MANAGER_CLASS_NAME, + 'className' => @session_manager_classname, 'enableLocalCache' => 'true', 'regionAttributesId' => REGION_ATTRIBUTES_ID end @@ -124,9 +124,42 @@ def create_cache_client_xml write_xml cache_client_xml_path, document end + def detect_geode_tomcat_version + geode_tomcat_version = nil + + geode_modules_tomcat_pattern = /geode-modules-tomcat(?[0-9]*).*.jar/.freeze + Dir.foreach(@droplet.sandbox + 'lib') do |file| + if geode_modules_tomcat_pattern.match(file) + unless geode_tomcat_version.nil? + raise('Multiple versions of geode-modules-tomcat jar found. ' \ + 'Please verify your geode_store tar only contains one geode-modules-tomcat jar.') + end + + geode_tomcat_version = geode_modules_tomcat_pattern.match(file).named_captures['version'] + end + end + + if geode_tomcat_version.nil? + raise('Geode Tomcat module not found. ' \ + 'Please verify your geode_store tar contains a geode-modules-tomcat jar.') + end + + tomcat_version = @configuration['tomcat_version'] + + # leave possibility for generic jar/session manager class that is compatible with all tomcat versions + if !geode_tomcat_version.empty? && geode_tomcat_version != tomcat_version + puts " WARNING: Tomcat version #{tomcat_version} " \ + "does not match Geode Tomcat #{geode_tomcat_version} module. " \ + 'If you encounter compatibility issues, please make sure these versions match.' + end + + puts " Detected Geode Tomcat #{geode_tomcat_version} module" + @session_manager_classname = + "org.apache.geode.modules.session.catalina.Tomcat#{geode_tomcat_version}DeltaSessionManager" + end + def mutate_context puts ' Adding Geode-based Session Replication' - document = read_xml context_xml context = REXML::XPath.match(document, '/Context').first diff --git a/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml b/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml new file mode 100644 index 0000000000..e8c9e5e2ec --- /dev/null +++ b/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/spec/fixtures/container_tomcat8_geode_store_context_after.xml b/spec/fixtures/container_tomcat8_geode_store_context_after.xml new file mode 100644 index 0000000000..bb29cd206a --- /dev/null +++ b/spec/fixtures/container_tomcat8_geode_store_context_after.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/spec/fixtures/container_tomcat_geode_store_context_after.xml b/spec/fixtures/container_tomcat_geode_store_context_after.xml index 8eb45842b4..19e41bcdaf 100644 --- a/spec/fixtures/container_tomcat_geode_store_context_after.xml +++ b/spec/fixtures/container_tomcat_geode_store_context_after.xml @@ -1,7 +1,7 @@ WAi;5sy1@gI5qsfmAA%KlON|67^;Z;nx=;^2>eox%Qk|7TivP2`myWq6jdHxIf(tFObI3Ab3rq{VI`Cf zqigiFe29=iH@XK2ybWF{_IqsSqRx?!%O=Qv*<4& zi95T^+^r-dw^`5Moox~mCI@#4l_5yjlqIh~{~RTgkZ?t4S&(%jSpWd#?@%HB9j$*m zGmw!K7L`*L-R*sI+TK_t_~y?$imNK4QB_PK-QK-)BSX_FqH${pE!n!GPt8Ig5rkrc zWB^cPdKP-ddp2=i>jD(omL*TC^Q*VhBo64#^Sqx&GwMHo)EvJF8__L$CaFt4&LsDf znWmz5a$fe|Wa=OJprmU%-`}5J=hE}8JiVV67nhfp`^hXnM&Ex^99LEqL+amKYkaojVkA*fTw}dmp!eGWWN_uEc-9`Fv+cBKMCt#XFT@B9FBhG;URN)z)1W$ zo`JQzSR-QNv`bLS&+w2dzMulY-qye>4}dfcuvB_j0W5UUHRnf6i~3DkF7SSV^Y5O( zc-ZRIsEN`MPX?b+*5Z5MXJ>D&>XtHyGbJciBYbJ5{1@|zErye zDu3hIMx;1E&g!XnQWr%TDx?9td%ai?{0PIpxct&Dd&y4f3pbub zj`!J_;RB*-Nyj_a{)UY+PG0=dNE?Oj%i$m4tkI%}G!WH0Ol~AX^-Y?rmqx(`M}S+0 zVW%)=X@gof%RLIEvT$sg^&SA-0P(@G*(ld*SQanaLyH@BcTc5R+F03c?f;1&`qn9m zns*?q#kfc~!r~6Lq|S<>L(P1G(J8C(;Brvp zkea?jD)`920+(!A8v*7P;XpQfV@4PjLg$a55$MaSI|eurKY+Y5)DBf#bUZNf@Rr_! z#bFN`tPX%2n5Rz|ON&Klz!xTX8KDF^D4y6ch2l2*WtlLYI!l0M2rtGNG!qv~1J;*5 zSi&{8%=gO1rOML=pMGbOy@Gm0%sRQT^f<&aX^vL*=1+3bK`A5BwZy6_k!_;?68z2t zu!GnL@=PA9Iu(TH0TWWC-{oY8%pWJBSJa9Ux+EE0%6*|qcHX|uq1f*Md7JjW(Ev_| zDCt|T2L^+f332oyNQ#KjV6nYm`u1C2^V}(|O5VX_aw#|K*q94&g?Lnc5!@7|F5jO} zEr^JWYa4~;F*SCZcZSke5U7@2BJG<)0i2-NQ&>y^|(+*2Xf?+h! z1!BBCpqn{}dAz9ZdUHbJW$6~!Jz#ta$l(_5--u#CYu#xy0w!v#@($6u?Dw&6tS0 ze!$jdYTAqBL>jMN+4N`HS~5dU)?@H)axI|<7pd+7?TpB~fADkW_ghKd#R*4c|m z^ZHjqsR~pgmY)@_9`n)>_s3sZkvJ81UT}w-np`ziRtbS%+ZpNEDERMwJKQ%;9+g`q zuXU`_befX^5SK@}GYbUK@`)WrP&^J(E4J)%I=ORd?WE_8MU$vthl?~KBB_`vnW)%B z(cs+2LryDIMt6YfDf04;q;x6=+5!;J-e_D5SyoUmWT5q4W;yO?g?+QU(Cl$dt(6E1 zf-9%kfOx&crizIL8oYJYkDpdM>JE$7!_Un$qh(&}$e2%BK80q#TvsJ?dv~dU)o6hN@@bRAZo@QNKxORf4UrNb5j$4yC z6;7Vd?(EaWfw}CYV47U?_7tkT#vH=#f?Q<6T_njh5-CP4&Y!}Nio{X^*@d((d|`BY z4Z8?;pwxxfFo~s)pjRpPrReKBwxNTNWZs+UnAcdjG`JzbG*o%J!`k^65fWzl*9(EB zN~Fcj6HNEG;WzO5DZFhd#;LA7)&AZ$;wosd*+E4n5CAzD4g#7UCA4$0o+lIkz@eC- z&>&%?C|rhE8%pqN9lXh9heD{4(k8~gK$Pt>TyLT~3*LE7gsuSbpzSN2}xX%9$ir#cu?yAso8id>2i57Zp9qJonp z;7DLExrrbTa8)G-Q}cCB2f?VlSV*F0SmY6XN*8;?AzABdw3SNCW1MC-{>h@tDT!}x zgXN^LlKr-J{#$WYWTwc}3vyVv;i607H*vqe?#gS@(;lLKCR$C(VQVk>6Z|G5ZS59- zyCO++D2|{9d@pfAghsa^5VgQUwa9zn67sIyNmzndx{t&;egx&P6+oH%(P7fBr2K-Y zKY$e96L9aPOkh%9e zN$-xg7A+Q37QM?CzcF#_fV5ZxP3~jM%vdy;@4=B3M*_bLTX;D-v$NuZAKx8#abd~L z%x<_(@8@I>K8Zh+FFyT<;HLBr=r3?>apIPYtfS#!uIv^xA&*U!vlW~qRY(+4X_KS@ zICEv`!FvOqu7?+&-aK5s{5)8D@}6f_9eliis&RU-b>qtLp+e`xm#+^)h9SV2#(o;W zLb$neVrFl5-~F65nb=9|4gKMTZt!KD!9rRO;%TNq4Z8>?S4XpE8g;~J>jAY98jtwR z8FjrWy}6~KN`P|cma0>ZrubZyQLZLyRz&Bg)-?7Wx7Nlq-SN`R_gP0UnohUuk!E(n zgHL$QO7MNcS{pnb5YNQqHiRX({47IzH3Y)ZRq8)+Kzd{e~q%Pdf3(+g!J4;fi7=(whhk@qD;4TjaeH)fnwuuIL$H3 zM(SM5p>5|xzJrKz69Fnn4XK*-~$1UMohC<@qP9htyd%fw^EQ*uhCBliKZ3j`Dl z!ZGpe2jst-F^J~{C@4%tGb7*>KhuqdL!j;sUvIgf^Ih91Q@VUBpxS_uN}C_pkY`g* z*iMIBKqYW#8RpER?2Tm276^T{g}6^rjV~aZBN{iDb-5|eFf|G#?l^^*K#=OYwGQ~* z_C@%mQh~KXkBQ!eWFb~3p&Nk8+Z(j=M_EiV&tn^z+BrriAgS|-30+N4)TWc*o{Ku7 z?rKKyupnkLT*+J}T{7!=^!*0SE)AU}(hTYvvJWunxnRg0KaHYDgkDFF`o(2Gwd6TH z;snd`qs2)@Z8KuadOOx!8;NZvtPK(fLYaDo-*e+4GS-bYW?=Z5`J`Ic(Bbjx;29n7 z$JePjk5CgjKy+8?H3+{ee1B0XuZAA#Tc-amG%rLkWDOLp8m5DlwBoQ;i`7dmS-(uO ztpb(-vg1bP(fp!R2EhFC{oc+i{W`%!xMNp6A)=z%!Y7~nEBmXN$lvf7tcSZQ_)k2D z@D^8PC0YbV02IN|wrhmjL8I+Fd$fD$7BKH0BizE0l?UJexq)cSP;a|}4b7iKjLx+)8oJfZBcU}3;VSA%htb{*985aIaC^dfNM3xTuVCp=5$Rg~JpyuH zb!$AwF*uH#{sQr=#KF#F->xwJ-)7%Z*I}+~JvIKt<6x5Ld2^^m^79CgtRJrdv7I~~ z(ZUscK_LN~=^68?G4jre!jUXmF-=5qj#~bV#MYWP88@hj$6AYD)`aEh1l{`bVc`uX zUZ>h5kGf6aBRPi*d6Kobhaqwxe*$%pU+q!*Rd2}}WRplVf`~XHSp%3GT0i|jAR&l= z8bW)1Y?7}blh>>N^aaxTs`uZ`muR^54GKg|o`q#Bo|uGxsm~$H8E=+4&t8o|<6vjr zwL(;pPB+~1gkg{MTJy{n;7 zT8VQk^8KwvbL;%x!9PC1%(Y$-%*!)G8VCjd$JL*xWc@dp`Pu5Br5GMgt~7>5jpDxO zwUdYaVX3h1<$-=z$u7XR;<*T=&d((lKjF0eUk+o{>(A@B>;zVFfVzGqH~ zryc);AKV=87z0ukCfzc_#&D5;T7EBh&5h! z@W8S43PYa!tA)d&{+YDq`E?_vZoF7j_o!;)6+#KVy9TYyW9K zr(^N=VV|v8M49-A&o*_+X2FR0 z+wLs~^LViUz_cG>V}hvh6Nf|e?AhoWN@a^SZ&6~RC^)I=tv+gey*bEX5&sY}+h64D zoyMLuw3mcsyYIM+pv*oJU-RtOHjlNH)aZ#YL5rO+5<57bMvn=huU$YWa9Pp=$nFUW zU=}I@;#ftfwEi$#BRaA}^EgzIOa1+El@^xZ`KX|F0u7W=WU;!h6CDVoUsaG1RYviJ zC_2fzLJ6V{V^%Tola06<97>TucDOup!$%z~tg+!|J9JQyW_)Ymmz8h}5$wdQo=SPL zp2630^x}w&-CQ|=G@RfJQ~PnYzPR}?^TV&=Og&h^s;(~%yx#tdtmy3N=EIFDy&P>9 z5d4S$^g|2^H@H7e++xQ>6DGyg+tWy}XC$q73Z2W--OYU=0Uo7v17x_ly>7^F3<_VPrA=DCvF~GL-=9-KZeY}kK=hUnS&U~hxzvh zg>Oqav320~hWDQPfsr|qm%AA=oq^yNPk!y1aAobuhM#@S&i(-MV#4_Yjr?&^+u4(e z*g`>lW5a-ZFv0;E0NodszrQOh2H9fa0yp*e`U^eu3}oXC0swR44XDpUa5jj5lO%yf@V0naXsM&zX1Z2?c>k9Uca3l{XBfRM(ph!QV@zK zZvk^wEQ1hYJU_#MW<1$ROY!F*)kgWfFt>}7S%?!}=KXLFo8Ar~=kQKI$537^oZP(# z55CzUt;)^K)78egf8leN-BbF-B$v?lkkZEeN+hLUz7j;M`O_2QCPis>M&l{dWYmjH z?cs9vP^;iFY|}1YmL1=qyMQQJvLIWGqndKZBOQ@V1RHl{@|}R8>4>le_7Fa@bO9#N%0*`0b?R*i>FUm)Az<2^&E2!9iYDdc$EG_O0NE$eExud z&-K*<__qiyWuZqw?5%?w4#BY@CLEn%a?X+lnPYB*_p}o$JPWZ~#C~+|`IP(JbPf4o zjaR;l+gZgdK*^a{l7wMIUZfbt%ANxZ$fs6ZrFwkF?nB=HfJTE3AoaNmXdb{o;u8%`GrDNqUs=hB=A z<;R8TEC(lQKWXj9Cpz+F=K*Z<(xnaDmxUs66Ad?cyk#Th(DvW7boaRQO!9d>p;Hm6 z)H{u_`!RmH$Ho~1a}HaqAm+H7+|}oWb|r;kWoXbVu^r>|hZNc{pK-@AF^tmw;bvAdCh9FEFSVVKn+u=p_@P%0=v&^OnY0^HYZr6nfI6RpSurKMJg$Q0Nd0 zgfX@sh|gr)vVlanzuIjO(_Du0$x=nxQnux-*+gl~0S(ZAcZVXRuRv(jcKn zmL+>`J_xa0IIu$bw$8Odd*zQ%=sg!P5X3T*_Hru0S{$5mdbdgcApnTB%>m~ruPWve z)&?EH8ft=L=9GYSQ3miW(PqA^IxHL0V(n#ya(fSgu@7|1Sw$IJeEX(X*B z5Ah48D6aGn@C~ZQTHb-vbhVyUzS^fqBJ54B#d;bzZzFU8oJMY7JRs_j>NWufM;5zD zKTBZH+uT9B6E_CJ&P;8|5I8<>_UAP~ZV(C{21AhQqp1D`a4+sW}s0x$*zok zpQHaru32DkyG)@xm!;78LZT(YxAx&Zug$5*CiM5l2~A=m0qq&hw^LtmdC14!tbAXf zcFrftPS8;T?Kq?{G4&zd+H{&o8O)V^f2#L@86tf|0~^&gO*i=7q)6X&o2x@A1%=7M zHYS&v<3W&3C`xasYcE&BTA+D_Sh{I~ZB3o{UpSN|hhdvOw8Pp{5KMUMTd7KMs@> z!+HpaC#-Ds$6HQK94?$T7c z;|$b+RC(D|=7Td?$Du?>l&hV~-`cBzkEkDWV_2IWvy4G6v*CHtDD+)* zE!Hfs3lgJ0WknEcwMgU^w*0qGF`epwrgH;*Vkz-Spi)f|~AZw5(ur50xDDD+WczWfDcZoTbD;w!uIlOO|7i z;ub9J(nM*0j_eQ(;s-HwD&46b;bIi&Hx9~eIp(qUD*N!F_PXF+3s2ZQ~% zp_KP2d>bRVdqBTcZ_HNQ;Hb`H3pXA2qew@2Q>C!m;yzkCG_AV{la*#n24zY2c}}hM zMq&CsZnIc+>fB=iMaNt^HYPF*#i%J%Z`;+|&B+)}p0)D}nEuHyHKHbjt`$`@AUxPf zeZv&dE;V(+n*PWBc;2QB#Ipp8)j7stzm6nquJt`h@#iBdcHTZ{)NBj5QAW)g>%Qat zEXNcsViZOya#Vv_II&y@YhXE#CaDS<<&mxM7py4s( zrz__*BBrOz45F68&4iX$A~*%X^!#KosmE*Dz_zHapI8w1+{+~N^(y7|M%-K;Gu_xi zqqTfxwSp67YC1sIE@+7?-&F1~{lPrT9?5FPSKVI)R~*=;Yg*1rB8$c9l?$hz=Uyds zP?+wNuX_Vcc_vpmD$mw*^i5aHnKLWQb!=5p$xxz6B)Gqic05ob1freg8cDCsvKh>h z%nEkLk8m)-Qud(-_;6p{;XtS#&Z@d~YTCv`+2H>(3D-#Ttg3Lu>mJhRXnVrfqeP2^ z2U|A;QR7s01h&&-=ZS>x5!JbuNO~zCDIwrs1O~N*>z6~uo`4#s@m1PUW#Eq|d4&2i ze=-v&2DcgH)0Sy1A}Df0JoS5##%!4ED<+6cQ4s}ilFL((+}1O4G@yzWqJj~t_uFeH zYS8khH2Sv#8_Ol9BJu5Q;b-;Xi!tnITE=($O;gvKD+gYlt2x1rt}zMUsJCM z9~%#To*cQ~DO$~p6JORZ8RdZ;!120W;GcIEv@&Rb&RFqeKCF$mmvH{~o1K9&fnB&U z=ChT+-Q&51{*?w{9fG?#-`>vCEU263W-P@w${BuL(O1}w2BNX{UJ%z~~Dqy{to zoBtJ(f{>XPOvWdNbju6Lzs-PfA>z1 z4nY^MkQOWOk?5^GgclF95V;6E2_NnDJE4sVnW+49{Lmv+n$@Snv6{#5BIdI@rB;cZ zo4q49a2v&yf4C&-OE4C8-$ks8f%+*>brTr|Kccwo3HevDUCl2?hcN`FU5$ZI!3h8N zf>sQCQ5~5x;c0s^05oLaXxzy(7wykjB9B`hD)C`-W4*`2;M2P1?>*V3~~PtOc#u$dxX2 zmKi9J&W%vNgX^`!7<$;Mv-yxepdR5b2s0k(I;67cbdB?1S$_nshgs_4zz&EQ z!vDxK!74FE&e1>ziac{+;p^?rl2If%@zMQQJ-z)pP(tR?g(o+&7y{&SW@UWYJ#c^d z%;ufU2XRbjc9+q@K15|dS&b=IMng8lw*%9SFSpy z;aoXD%aRN8i^&Iilvz4YJw-w1AO*wbkL_6EyA+`-W2Z)=Ck9$H4Swhjvi45rg4YAF zzjCJY-_M{~P7hB{54=2_%PW3LPO=$|ntjz#hHXa%1Qa<}j-CRit6#hukLl1zVv|?Fkq}~hX-jpIs_}1L(x6G4;>b?ILERxSuO2M7ka-xh z)d1X7M87Zxp|&X&||J2k3K9b zX>6li)>+r2w$$nwm_Yl(N#(7u80R5|4{~?Zbmv5E>q*N@QHtrGehSP{(X7FYiE81) z?&RutGs_&sjNHG7HdfpgN!;-Wc<_1Iw1_}drgl!B_z}ZtZ&KW>9;#tCp)VC@fMiFM zo#Xsi|2c4Fj;f>Mgj{AFOXl)N5BiOYZFptT9Asw*Kd?Cb$iLEcPUyd4*rA5(S{(*oih z)zN8L+tbmOgb$@}l4I({H9$Iihf2+}%awS}mSccOzfXdQZ}+JSoY-v0MkayL+f9|5}D#*wYx z5;O{3fE{+7J{B3V*A>E2Jvy>JS4jZ0W zA6Rz52i_;&0TUvR^9vtzR`^h!+z^^&F^ibuD*D*)1r4Cy2?5k@`QFs%J#iiFV>}-1 z#^Fh}!?483UEKm$f#L=Q-ao|4Jp$W#f9LW6eSSUVddlm1FgZ(e3fK7@e{4^Ks3WwQ zs|4}H^=-y*<&Z!Wz$*n74)GoPC zab=Clk?WQ3RLtl&87;#y_5{CzbceyQ3(a!}PG=ogFn<7!4PEn!xaWW3J#}3b`IC1< zyDmD0(*)*)8y%q(-&*D27w@FL-?JQYE@d+~p971?>YdIQ2sM+8_$Mz;*);N_P3?CC-siHX>J{Lt2#0Cs@b z-r&Ygq(V#LJl||))_B4!qGe<_dTuRr@LoeBLBTk#aj468>43Bp_)@@yie}xiJc%H_ zK#aIaJ7A61BEqBhVl+YsXKBkDEguO7?zZ7TsJmgT6P-w8DU1-QMGx#<8zVS!*mvw5 zlj~Pd1@n5<+;2u4W37W|)+9SFF0%s{63-(+rQjajGmrqIG^KV!o6WES8KrJ|x6iS3enoq;=LLVk{>0cUk;DTHl>oI~Yg zHB(A2;)V;6ds4C5*7ALKcrr(CU_14obG%a-f(B%?$fSOe@NK#zK?-Zpm5~P$2#>A! zp#b~v$=k6sI<N6>u98Bor@WyJ&AdS)%Ybu3;`a5(JaWJ@?yHq8}Ut7i114hgVS{d#h0FQYH|sL zCfLAX)V+tA2)({a7m^~iU=;0-Mb?=J0Br<1QVoh}D~Z42ebI7kM!;FVZ?r$O@m8z||?s(Tf`776a&WPGQy?*y&Dj zwj;~~fK86lx7A!hnJMCW1&0q11i&drk;51-1`X0RohwauHU%#&PzFWJx&k)=4Y7Alrm!?&q5WL?X3T^5*?} z>|7Tw{aB!Ki6z|+vZFC*Nw}T{`v|!vd>HwR+c7gjcB6V8exj#~98Jr}U>CG%y$BP+ zGHyEu;(5g|*)?-b>sa#sV%>a;(d*g^8^hhB0{F(2tsz0~Eysp7Pv?(B9FjnM%S~Y8i_&KcFv)*HhAm2Npsp0qWTQ_-t@O_3GK+v(svguH)kc&kS+=jn5mJ+3#YU zFumCNwLqa2Kj9V^pYO+}!~(OfWQYqwX?c!DV;xshc}#<1!5cIo^_?ZNV}@}pNQ>S3!kMSbd0dj19Lh7-{9KKZS*2Nb6bq3YFBteOKK}Qmz z9~^bScO130s;su(xMqa5obhd1NeB>q&Ykv>YW9X_$D z(0#A@$R)Avf%EvME(Y0+i_j_f+iG@$^H#I8d)Oc!}>DDYUZqpH9DmiS}Wf|XW& zSfDdxl7T*{^V3k<@F3BMRo7&--GdB$m8FmoJ+giwjK9O2`pTmTm1&W_O11i8T6M@p zl&IXcvt`z6TK0@Wy0E*nFS-#@vYc<$ik*zRwAC2n-$}uc?}x!*u7sDa<22{}iDyu}EmRC<#x{xm ziL47oYnuesz+0MB`q+$Zw;PPt>1~@N+q0~BGxX$}g+|eqA!a{$HUtsO$m;SnW=cfy zBWVt*tA;XkPl`@^#CFprP-{LYJ>;zLMm>5hojjwZd)StlA}-}6BHja#LHZ@!LK+&x zWG7qv{1SJfp3O#)r&#o$6-!0bqso2LtKqg3Gs{URh`9qnH|DN~yo9_@OjdW%#HG+sGHrI~cL|%@RUIAiiu9Y1Yqcq=G?ZW(7;oXh>LZ zwZ{j*5%0QET{iDBXSD-CE7FZ68~8PTf`>k9(DzsAk0K z#nr;sjb*-veKy!ZkS^bDF*qwxGMHEbsPfBfx2$b`JQk$*?)goHAR{dqeN9}6YI30n zkViy?+avZlW6O?oVmqaR3DAI>c0bVOl9d=0i2BWHI}vD}4b&7ryZAYF8=>5w7+kiJ z{Pt1YdM3-S(DWG;CJQ!O*~8I1^QC%9qE%O4IqFapMxrQp*EMcr1;Oa2S$>W45Eib; zhtts}F@*VERtE`$61t8`g(DiGZQu>8zL8zAQH}0^pO&(sP)a0dsmi!jS3RK(=ZVy4 zv1opjWp8+eCp=wwW>S^ zSpu)1UrG9CNub-QlR6~jfIC0F6z?Rg$sM&eiar#Xcr!E(pzXjU%NCLjDKsv01%8CIP7l3a!V;kIz{w<3qnd!8+ ztUVnxZx{!6B~iJoCQv-hmU4&WnR^ALoW@wxOZz_ip2{Q7tiV}5_588)_emL@tj#f# z6Y|i_U`YCQ;(Ak7jEIA<8^t0aoBCGVKXnQA@IS(68&mB$Cq#dSt7SatZ;R{Z{!C_K z3Yf4yb~~sWr1}=QS#x{XIfpxn;y0d=Br~j%7}nLjV`b|lzu8w~g|sD*V_b!6kB3$= zMae1&43a55@}gO1POVDDyA9~4*A5C|=aN##`!28JA}r*hlyQ!Ei(#<|`jC!*$V>>V zSt6R>YFChh=$grlaMt2RKx|Er2eVBQwq%IICDv?_E_%E%SyI50t$INyoUnEgh@hO1{ z>juFSbGnP6i|s`O3yq%qI@!M1v}~H^VO&mX{a>>0q%Y?77rLrZY!cXS0akS*;slAU z-t(k9aXax!Kv^wc17Or-JOxnPa$rCCw~iJ#IagZiBfC|g6{Gzd6!C)RR}Sf_487S| zU_~9tGumhTYHL-toZBl8@isB4m8DhURaDHC;kjVW(G5M`HDEgi@7BODysj;+EKSh1 z?H{M_qIU0lM=L~|?n#~Hq{-c(R3{Dl{^U6PN&Q;$Llhz=Rc+|IpNifj>S}8u@gH`? z_3;+&E<8_JckR3wsCWiO5Q+#@nXFdq*incuKnzAk^Xy2z3T^B%MPgyRXMSAf=@3?A z#!CzS=Hyud$C_`0L*9WkDkJG%RMOzglB)=s+7XjAF6odpG_M>{7A3`JnE-!^vPNt2 zY?;mQeMYWVihNtP*{s?kSrw$WdW<)vKt?Axx`B`tbx-3AZ60B0E7w zW)D@LZRGysxCg#M=8#BY?OA8Z?)41Q4o~g2$oIIGWsab*OKbL{V%rRQ1rfIc4}JRb z{y7Q81x1#Zl%lP$B7;vj(J>lFJGJl<5T&KtFyXAre7i^8yl4!+LFF1JxnH#r#e%$gWEpzY6`_HB)gB^RHSJdbTMHN zsX1Zaxoibh5&sg>qLtZkc8>Phni`$pN!=wz5-8r=k>v%m6)1g+RYR>c!A1O$H|4~9 zgrjFIN&<;a)Fe)D!w@Z`2s|{!`Ivl?+~)jXfcGqYFRIg}89k3w(L_9&$o!Q);Esmk z`ytTz4?d)+!gn&{T0qdI*Qrv*RuYjW$%na(KnS9sVUSE{Wfys-^RV=>ab?Okl?A%C z^}Qrkqa={!Y@T%^m05-AZqaPYIn{S_ndp%Ourl^a6bzY!3+Plc)}SSdg$hcpWee&{ z!TlA>2Nh?sIeBQyP>6yHIcqia+TtKgK!*68(I6T42!P}I0~BAMKOvfDqX=X1D2aT- z+^~J=7;~xvULOwlannKAxBp005IL*|mvM7LMK3Q6J>uj(!4TSnkN)63E#*3d;Z6$ z3R3VDJ9Q@(cDf!k7+~Arffd<7bxLh2jU%cTT?>e|s;Du4>cEmu$Ld`0HY<74O7K~P zrYZPfqv%G>uLgKJ&V#YH6N+tP_49UVM;4TZ3|R$mL*K|*nprL=`Ark~UOlJAhBg2E z`v*Tv(ip)Jk6x-XptU%S&5D!0!B40YZ9hX*kcmDA>A{R&A4GFhX|Tvs&WJI_f(2!H z84+@~eap|6#IjwHpE~G?jB25(^Nc^jgV7o0l`_J8PxGK8!)A@^>}@hRI3ADtJlRX+ zUQ#sOx%)i%@pOKuWBr;*dl;_5*C+*%wo}0Ez0RIM&l#3bw-3-O<{PD53&@r;Y;niO z9;JFuOiB1~VC->IRh=>68aNkUKO6QCL1W~2`u%+D@%U|IMQ2AhA7%{Q$=mfqTn9>| zs=(ssh=IHo?cF9(buy3^p`=%JjdSp6 zdV^O1=^e{=xAX4Bju^-ay6GLTLjoL6ABRs4F{I91R~Ic(#TNu-0P{#< z0{AIU#Y@qevf@|9Q>U0cBjS1rMeG+F+uY_smjL0#{@-D*j~)@C@c>f8*X6&@1nN)| zuX==O5P;KdU1TAEy+~ttvhX##M=mU{9dpL}Kn~4l>_LW?RAuc2-l8N2i@o9U@uKW( z#Ge7j1zp|3&iUcW+Wg2fkG>6#OM4Wr*hm3N?|6I5rI~*ZBq!xvp5B6zf32ONf}c+-)k@DEd31QGf8Cff zc{3VJr^}I=J^mn+Fwsw?l-D91pxngwRsm0(g|O}H*oOn`FA!9%f{Y!n0Gp;(90(0+ zCdCOIQy_?Y75jYF&SoIW<8N9qM?EeJ$Xp>BYu#W5e7M^2NFs+az%@y8QuAS_rli^u4OyOAE+U52p3)(~$3l=qb%9z~Hn(U=ID}FhAEH8Cp|T5( z$;c~=r9Q(HJ0_VRcC13#b=msv=_d$B-m@_KZ55|ILb1ed)r6k<^+G^Vt*vOpZT8G? z0pXjov0S96Ei6(wuC!o`4ha*yXcGQ_m`y!LYr$ljn^vQcXRRW36NN3Y%{?+UTTm;E z6MG5ce$U9OvvqNanYS#@t7sWQ&v>?7j|^V2l*)hTktmBcc~KvRktKWrD$4lm9WzI z0Xo0WomjooEUf3fC|}JrvP{#bxYWKm$?t+88UWfwCVFh=5 zPw6=?3~wxX9;qd>3N`}$?PqO?1}UTKN@UZ^TH<`PSvxNI#HU9_p!{ZWM?yZy)~398 zb$w!#hb{aBB?~k`T#Fpd3-9}6gl}2jSwt*4#b8W~rkgH;XgRtli{4s4Iu=dRT<5DT zuhsxp`E(dx7Un1f<~5H;Q14J$wu?(2UKo>8HC+M$JWncd6DHB#j3MqsZFVj#L_##|xF80M!>?aAWrn#^E|&sixNLRWr;cFsi^~qxAno#hBJG?aQ42tw+U12s@z!>tMZo9kq<7k0k3Z9 z#c_YS;rH}flV;3lAu`>BagkPRI*Exs<{s@exMBwx3%v+5oiR z@#luV!*k0%R~`c)b0(11C7ejkxl!LoJLzbRh*n#)Vu*Z3C0{_fBE*9#BFL`;P1zMWPo=c|2gUC~|+a+PYY^ve?2MeB^9# zFXF+93&cgliK$qa$ePPUtYG(7J6j!+xYk0P)4a+RV?=C;k04z`M{xBt^qOxk)cD5L zA3gA;-3;{ZPJVEyla-YvvC|08*gwT5Q4-JA=I0987)Z=hu?B6P$=D7*lA%hUOoG`K z?acJfny$9ZI<>?ZvVUOKRAkGO31?RPq0o$0U-qpbgvsr`OZW2N0L|Q$jDfoAp!N>$XVNqH?!Fp@YjV{7D1e-QBz7wND9+@eTD*M7}(_I%a1_pEXWkcCwVogr3)S=; zgH-BQN~C4qw4<*kt&SAT7R<6VQdZVNu^skAp)|bP2)ifO-n02jN;Ddwuj)k+KS_g% z+AGnXN`JJL&gHw_VUJPF5=Uf?f7k}27SGs*gu>|aJj*`_!7wZ?6wI;nY2pibtHHre zb(``4V!s!K$3*`C4|PkjJMVKy)W8(?h?SeH-e}l1PR$LL0~u}b$sSGV5S>6mlsuoI?3o4)0vz}#>d2mxQjg%D8`X)N9bgz_ZpSu6ks&^X)ijg zAJ8K34~$R37A*w7qUXUHmdf3I`v@=rC9UcGvo*hd|JtcwPM*%s3s`JvUcka8>52em!_hjW!F{d*T}Wz)8F2`ZgSZH z;p`l&wjHZ9Y|jzQW6(HjW=!*P%}jK-dF+#Z(&0GX7Es`=9l|!h&({Xz?s(YVQxccJ0SpKeK6OC1;cbk;^X7aM@-e1J$&rS z51Nma^ML8Pgw2Gz>_mRc4Yz~gZt`thL}D3#qRY~iy#A@k`i0oLi|ARWf{YzeF$u?v z0J+BFk*oc-1+!jfjz&DgVvw6h@W8fJE%)X8XYIvYJz;!J#QfrRwJ~((d(SRaNFR%Q zE#4MuQ)7uP@G2(s@w$k~#F)DBgoit#sj-DkP$Vrjwglfi*M-BE@}oF)$2xOaMS7-* zNN{nXB1O>=l`EC8HBEx>3Srx6CwyaUg_PSN*~x(>M5rv%M#+Q|emC&WkR zvem-m(=>)+xw_6`TfJN(OY7=-6y!%K>DK9IlS*%1-e7@S>{2!mSCdpC>iH~U{R$VN zbxXF|!qNqy7+OgSk@b;$$;4*tWKqN1&GEv+1!9in)j_q~Y++X(Gq)AKOOzKIyJxhL z)nI1g!rmFnRf#;Gsi+7fqD8jc4A3q6t|BiCRMr^(?pZvG7aT}H5@@fzKdUb!I)`zy z_4sL0@sUrQ@$gBd(g;yhE~^G?rZVBGbxh=804g703|*~ac}ud4~j z=+x-4*7%+M&S=A?5He^#PF9F>e`Ob@?11g+12bq?9u66OMp?7M?P!I_&qDC%z=bucVa#_Zt0~+dUQo% zIjJ4j*}xY5uxP8=(x)t-J$$10;blYs*#oGN`l|Oubgoz#bM}oWbgjGL%TiB{cKz+k zQ+dOJqc@(>2nahAxni9huR6b(H$7R3$WPC`J(Ep1603i#b<|y8!%!aeA|Am>>m_r8 z)bcRl#n>AQ0Xl1;FNY`$ghrGJSZZ+fy9K0oUh-bCc==Ee&Wzi~!Wybl(0>Rpp_647zR zrX>qXaD%x;@t)S7pQh$RP^&*YhKrgM`)V6c3KL0CYtBM07+|b}EP-c`S){YpR;Dk2 zvSgHYnsgG zGa@jF4l4jvBP+3Mte4{E6Qj%Al1yA%G{iV?d(#kS?OHh#TliBc{AGfUa)$3m`FHyr zjB3r^wVKCgSi~ip0T15}+6@Wq%}+#;2ncOD&tLJX+eq^Wz2iB45t(d|bH+!i;k(6^ zyQ9@xV$(EMLUOM8Ws>nc3@jA)(pgSMqs=ei{r9B{RMf`B5E4W=m?19pMbMJKBUW=1 z!kV+>XSil34;@JQOW2({R&2u?TUXQeZ6msELzBEt#*ZqpSd9e;)fG8${9q^`!Nodd z6Y_Tb;}CkXw@EIS22Nz6T{;7K-$tnT2GC?n4U%<0sc6iP#{wIJrzgz{Rb{%?B8IWM z*mufhQxil4Ii*H>)9Ij2XDZWjksZC|k!hX$%W>R9jJNZe{gE*@Bon@IOO3vUczaby z&gb_Qp5TW#G@I1xwRIqLacOwH)Ku^ihruUP=~?V;be!TGLsHUCvN*V3ob+`Nx^%nM zEGOu>-}=yQTVf>5(LB0I#CK;)>%=ieg+%Lw+~T<@7Dk(wI_)`cn-?C@xciaHZJ3D& zD#q4oEzvm5V7Y@&xQWQYx6*l2o#-@^*(=00ucLll)0&!qIT|KSiI>>L-K%&(q~o1K zt7Us0E!WQ`!aWyC#2?!)h`nI`-AZJwG%X!0!<8{oGteI4{U!vi@$C1E9 z=f6_&xzg&E7*@46HAd3*Q=N@5oBOr?(1o-G+00BfawonlC|bl^jD5V~2EHxGgx_L z!?&#<90Rq%B&xojJ9oonJYjVh@H+&Rm~P-(I2wW#Syvy-&y87++kfAuK=xTY9cI)n zu&u^#v3TsM*d#m~n zux|F6#UWQJ4oe1oHX9X7?z1?eR#y`(gv{uf5%TqET^D_svG_11^MW(7JhTtNZ3~F;(dHJ zj6#XZvuk1l*S+K?W;cajeh zuz3q)_T^9SHNP%4}?!hT~j5o_B~rzvGRBjlgyZPx{4J z`U5`GYXd)Wd_iG*s&??l$;IY6_8Xmb3iu9MvJBw{ywfF>iR}Vk7GC+xVHUe=QYA8% znHBOs9lM`dz#mYqql+cS&m!R6-T$Nm(SF~?#L2|W%KVp`V*l%=|KKQpSwQ@E1;6{1 zzbvHsRUz0M47PT3_+P+*vZ6%dC#-o; zL6a&~8NehkK0?hQ_i1ydhgTk&``9b@@d%AIsaGDK$Vk9Ld^fAOIoX>+pX+`bwr)wS zvx~8t=W{O(Emr%lEatLKZx07P!Q5ZEX58smR-Fl82oxp`@bkpjV1x$F1}PyaSr4Lg z_Z&$wAe1r=Ec*u;ARS~|p*aWQ1->*0VQC*-uw}H-+5W7CH(ky;6P|se!I0j`&2<$R zqa4OEsIXgq|D^&{*?qxNcmMVMmybF#@DJ*VM577wP7$b#@DASSc}b+m4z?*sxWP@atjbS_Yhrn3Oddy*qN=C!S+JE^B~YZ z*V}d&ou06R|Bx>WYxxMJ*my)1_4F9?p{tLkq;amKO$(WumDQB?WPOwZqj)69ksOoy z8W+}8>vax&51JBgp9=(kX^XX7kEwlhfXIPfW5ItoSKW1VwT_Oi7JLl{Wmwl@%>7e3I=?im0Zi8`EU}S&vn%N? z^DB+ELDwsT?U|8k5XI1zIr`}+H<_E%4&pdn5@~)0fialA3-AxZ=L|>c( zODbRN18v&sg{4(5wgQZjSYcQaHd45V^j?VArf((nhJqt?5a+GdBQpXn`1CGc4c5LU?s;FAS>uv8%(wK^`NX67$<_naVYb?-Q9b~rD&pfd+Z-?)f?g~j85v= zx-5nEUekbr84b^yg-}`O`N#E-`QN)R=DYPb&SEo(ozv2+zc4*;YHPjsI^l?$>``i5#>`fo#>eL0(gq?vgBG!XK$U>0!zz^zelw zD8{trGHLe*@t{Kd8-oQSm;*d&HE!0jH^HXc>l-Be7y847HZIAz;5&oMgJTwMzXI_Wb#WohTeZ z#SjSPxPMD+R$}=g4z)JoC%*SM9~mn{jZW#T?065STOGH|MTyHyrVUO{vWh47LAs6E zq)dyeEwxUHC=^YtW6Gw81;e;^-^}OP^TnCXbsuUrTyJ&QZh_h9q?DNK()Hl@aA#zK7K@z zC7CU8@jgG^AkKtZA34>E4f~sZD&0X1R61cVws&12MCtUq6iZzWkDNm>ZQ%>;q^a4f z3vJF!X`h&R6`rvdNnMQ+AbjrX4D8ZXN3v8o%Z<&PzIp3`^pz{zc#nwYGLU5ux+(YI zsW^fB&89%OaQd@OE+=PL5E<)%Z@vGfM5|NaD`Y%Hp8756XM=S?Oy2V(F$JXl4P~Hj z1x0&G>M>Lt35fYi$NA}btze3nGF;ZN1BeJwN*GT2HOpCHYpR?6>1z`G;UO()kQfH* zOuavR7-shef~R)I65XVmAL9ZF`NJA`%xiu_jB4>_Klk{#;g z8CJ#dv5`m~8nINOhv^F-tAiE+jy? zy8ti=o+!0Eyo>&B;RX0RjQwtriJzxQl)LbMyJ5k6m-zA9KaJ#{%YG)Of3Jhd^<(;L z*-wiu{ITP|KpnP{M{By^@H!o91`vLo_!XMN1pM@6xTKL>kk0_KbYfZ;Qp_YIN<+-e~#z>jQ{`Rc>-=g0zd*l0zd*l0zd*l0zd*l0zd*l z0zd*l0zd*l0zd*l0zd*l0zd*l0zd*l0zd*l0zd*l0zd*l0zd*l0zd*l0zd*l0zd*l L0zd-)zY_QlnC4&m literal 0 HcmV?d00001 diff --git a/spec/fixtures/stub-geode-store-tomcat8.tar b/spec/fixtures/stub-geode-store-tomcat8.tar new file mode 100644 index 0000000000000000000000000000000000000000..945fffd43f5f3090c34acfbfdf57a437d32768d5 GIT binary patch literal 30720 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 literal 0 HcmV?d00001 diff --git a/spec/fixtures/stub-geode-store.tar b/spec/fixtures/stub-geode-store.tar index 816deb94d163df84d7f623093bba2a8fad996123..be8271f25b7d4d72e5c797a1760608bc351b2f8e 100644 GIT binary patch literal 10240 zcmYdK%}+_y&CO3K%}FiREy>SKPAsw1%StR_pdK(VG%zqTF;Osp0Cd{G%*<55(AW@& z3=GYTfa(lQObiVf6bz{61l%T-7MB1$Ye2DG=$^xExJwz zP6ieRU)K;vT~9wZ{ePzz7?>FXyxBQGN|>PPaBCI;s(@?ub@cOea}5sB^L6{|d*-x{ zx31nrUTpdOKD~N5LZ=uzC_F7xwz;P zan)%IQ?ox6eJo-GJL2az?!V4JD_npWXI;YpZ$>5& z22{VoJOc77Du6p4whCdGxO2>k4O}>Vb6}3+!3M4}VV0#wRUQ1LBt%lCJ)N%d z>_G^7$h2u~$7MRgMIL++U}U^^Mn{Q9Mn;Aw=xp`g38@y65fU}A&N8L8fA4(xKQ}2M zflVvzIfJL6;1wOFBL!#o_0`SGTX#^gYG2;`+VgY1eY|#c_lehQSC_s!^Yg4DTX>JW zjqat-pRRuVvNvK^SF7=()+ZA)G}rdXKU$S_etJfvjktKN(mJc&#H?@27xlaLB)I?i zbL{VR$&6O+D}pgRJPz%gi!7NmPBnO(VZ7Jlqr|h~Tx%uElkkv+N5v&;Ph9I>kg@sb z!~6-HF+4lwb~3bIkU4vbO(>P^&{~IIqW^BF$i8@Z^1mDN#Q(l$4*tAWoCs< z8?;n^%Ex|gcvA0L^YcE3rSR%W^Z$oxp8J1ePA7xL&-)$Ee%6chGzA)PxgFGyU|pO* S6vtVffuSPu?okE}1_l5jImZhC diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index 9ddd46b1bd..712205b77b 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. +# Copyright 2013-2021 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -60,12 +60,13 @@ it 'copies resources', app_fixture: 'container_tomcat_geode_store', - cache_fixture: 'stub-geode-store.tar' do + cache_fixture: 'stub-geode-store-tomcat8.tar' do component.compile - expect(sandbox + 'lib/stub-geode-store/stub-jar-1.jar').to exist - expect(sandbox + 'lib/stub-geode-store/stub-jar-2.jar').to exist + expect(sandbox + 'lib/stub-jar-1.jar').to exist + expect(sandbox + 'lib/stub-jar-2.jar').to exist + expect(sandbox + 'lib/geode-modules-tomcat8-1.13.0.jar').to exist end it 'mutates context.xml', @@ -78,6 +79,53 @@ .to eq(Pathname.new('spec/fixtures/container_tomcat_geode_store_context_after.xml').read) end + it 'prints warning when Tomcat version in buildpack is different from Geode Tomcat module version', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store.tar' do + + expect { component.compile }.to output( + # rubocop:disable Layout/LineLength + /WARNING: Tomcat version does not match Geode Tomcat 9 module\. If you encounter compatibility issues, please make sure these versions match\./ + # rubocop:enable Layout/LineLength + ).to_stdout + end + + it 'correctly detects Geode Tomcat module version if different from default', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store-tomcat8.tar' do + + component.compile + + expect((sandbox + 'conf/context.xml').read) + .to eq(Pathname.new('spec/fixtures/container_tomcat8_geode_store_context_after.xml').read) + end + + it 'does not add Geode Tomcat module version to Session Manager classname if version is empty', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store-no-tomcat-version.tar' do + + component.compile + + expect((sandbox + 'conf/context.xml').read) + .to eq(Pathname.new('spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml').read) + end + + it 'raises runtime error if multiple Geode Tomcat module jars are detected', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store-tomcat-multi-version.tar' do + + expect { component.compile }.to raise_error RuntimeError, 'Multiple versions of geode-modules-tomcat jar found.' \ + ' Please verify your geode_store tar only contains one geode-modules-tomcat jar.' + end + + it 'raises runtime error if no Geode Tomcat module jar is detected', + app_fixture: 'container_tomcat_geode_store', + cache_fixture: 'stub-geode-store-no-geode-tomcat.tar' do + + expect { component.compile }.to raise_error RuntimeError, 'Geode Tomcat module not found. ' \ + 'Please verify your geode_store tar contains a geode-modules-tomcat jar.' + end + it 'mutates server.xml', app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store.tar' do @@ -98,7 +146,7 @@ .to eq(Pathname.new('spec/fixtures/container_tomcat_geode_store_cache_client_after.xml').read) end - it 'passes security properties to the release', + it 'passes client auth class to the release', app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store.tar' do diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index 1c7ac0a807..f25af648ce 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. +# Copyright 2013-2021 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -47,8 +47,8 @@ let(:lifecycle_support_configuration) { instance_double('lifecycle-support-configuration') } let(:logging_support_configuration) { instance_double('logging-support-configuration') } - - let(:geode_store_configuration) { instance_double('geode_store_configuration') } + # pass empty hash, so tomcat_version can be added in `sub_components` method + let(:geode_store_configuration) { {} } let(:redis_store_configuration) { instance_double('redis-store-configuration') } @@ -75,12 +75,16 @@ end it 'creates submodules' do + # create Tomcat instance double so we can pull version when creating submodules + tomcat_instance = instance_double(JavaBuildpack::Container::TomcatInstance) + tomcat_instance.instance_variable_set(:@version, %w[9 0 44]) + + allow(JavaBuildpack::Container::TomcatInstance) + .to receive(:new).with(sub_configuration_context(tomcat_configuration)).and_return(tomcat_instance) allow(JavaBuildpack::Container::TomcatAccessLoggingSupport) .to receive(:new).with(sub_configuration_context(access_logging_support_configuration)) allow(JavaBuildpack::Container::TomcatGeodeStore) .to receive(:new).with(sub_configuration_context(geode_store_configuration)) - allow(JavaBuildpack::Container::TomcatInstance) - .to receive(:new).with(sub_configuration_context(tomcat_configuration)) allow(JavaBuildpack::Container::TomcatInsightSupport).to receive(:new).with(context) allow(JavaBuildpack::Container::TomcatLifecycleSupport) .to receive(:new).with(sub_configuration_context(lifecycle_support_configuration)) From a537a8a7174ecac122707ec0e228cbf66618a834 Mon Sep 17 00:00:00 2001 From: Jason Zhen Date: Thu, 18 Mar 2021 10:39:28 -0700 Subject: [PATCH 624/812] Updated Introscope Agent to use neo mode by default. The neo mode helps to improve the App's startup time when using with Introscope Agent. --- lib/java_buildpack/framework/introscope_agent.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/java_buildpack/framework/introscope_agent.rb b/lib/java_buildpack/framework/introscope_agent.rb index 3e43ce13f4..abc5ecef2b 100644 --- a/lib/java_buildpack/framework/introscope_agent.rb +++ b/lib/java_buildpack/framework/introscope_agent.rb @@ -43,6 +43,7 @@ def release .add_system_property('introscope.agent.hostName', agent_host_name) .add_system_property('com.wily.introscope.agent.agentName', agent_name(credentials)) .add_system_property('introscope.agent.defaultProcessName', default_process_name(credentials)) + .add_system_property('com.wily.introscope.agent.startup.mode', 'neo') export_all_properties(credentials, java_opts) end From d9065387a1414b7f863391d9d6ad02401b826dd8 Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Tue, 23 Mar 2021 16:49:14 -0400 Subject: [PATCH 625/812] Update CA APM artifact location Broadcom is migrating CA APM agents from Bintray to JFrog. Bintray will be discontinued May 1 2021 Signed-off-by: Emily Casey --- config/introscope_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/introscope_agent.yml b/config/introscope_agent.yml index 5a9095a913..2675cbf308 100644 --- a/config/introscope_agent.yml +++ b/config/introscope_agent.yml @@ -16,5 +16,5 @@ # Configuration for the CA Wily framework --- version: + -repository_root: https://ca.bintray.com/apm-agents +repository_root: https://packages.broadcom.com/artifactory/apm-agents default_agent_name: $(jq -r -n "$VCAP_APPLICATION | .application_name") From 8f6eda64e74d4b3b6403b3dbaaa4f99f5a113251 Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Wed, 24 Mar 2021 09:41:11 -0400 Subject: [PATCH 626/812] Java 16 This change replaces the non-LTS Java 16 which is now EOL with the non-LTS Java 16 which is now active. Signed-off-by: Emily Casey --- rakelib/dependency_cache_task.rb | 2 +- rakelib/versions_task.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 2a497e2390..6c06404e00 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -132,7 +132,7 @@ def configurations(component_id, configuration, sub_component_id = nil) if component_id == 'open_jdk_jre' && sub_component_id == 'jre' c1 = configuration.clone - c1['version'] = '15.+' + c1['version'] = '16.+' configurations << c1 end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index bfd1df31f4..8d88653145 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -72,7 +72,7 @@ def initialize 'jprofiler_profiler' => 'JProfiler Profiler', 'jre' => 'OpenJDK JRE', 'jre-11' => 'OpenJDK JRE 11', - 'jre-15' => 'OpenJDK JRE 15', + 'jre-16' => 'OpenJDK JRE 16', 'jrebel_agent' => 'JRebel Agent', 'jvmkill_agent' => 'jvmkill Agent', 'lifecycle_support' => 'Tomcat Lifecycle Support', @@ -167,8 +167,8 @@ def configurations(component_id, configuration, sub_component_id = nil) if component_id == 'open_jdk_jre' && sub_component_id == 'jre' c1 = configuration.clone - c1['sub_component_id'] = 'jre-15' - c1['version'] = '15.+' + c1['sub_component_id'] = 'jre-16' + c1['version'] = '16.+' configurations << c1 end From 56f2047097503d4ec77cde3eacf7ffac89cfb7a1 Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Wed, 24 Mar 2021 11:01:45 -0400 Subject: [PATCH 627/812] Move tomcat_version from config to a constructor param Signed-off-by: Emily Casey (cherry picked from commit 1a9733e572d35263fac57236333e1b0ee7c0868c) --- config/open_jdk_jre.yml | 4 ++-- lib/java_buildpack/container/tomcat.rb | 4 ++-- .../container/tomcat/tomcat_geode_store.rb | 17 +++++++++++++---- ...tomcat_version_geode_store_context_after.xml | 2 +- ...tainer_tomcat8_geode_store_context_after.xml | 2 +- ...ntainer_tomcat_geode_store_context_after.xml | 2 +- .../container/tomcat/tomcat_geode_store_spec.rb | 6 +++++- spec/java_buildpack/container/tomcat_spec.rb | 6 +++--- 8 files changed, 28 insertions(+), 15 deletions(-) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 29947ec635..2cee774cf4 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -25,6 +25,6 @@ jvmkill_agent: memory_calculator: version: 3.+ repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" - class_count: - headroom: + class_count: + headroom: stack_threads: 250 diff --git a/lib/java_buildpack/container/tomcat.rb b/lib/java_buildpack/container/tomcat.rb index 8aa40721ee..ac35237ec9 100644 --- a/lib/java_buildpack/container/tomcat.rb +++ b/lib/java_buildpack/container/tomcat.rb @@ -54,12 +54,12 @@ def command def sub_components(context) instance = TomcatInstance.new(sub_configuration_context(context, 'tomcat')) # pass Tomcat major version to geode_store so we can verify compatibility. - @configuration['geode_store']['tomcat_version'] = instance.instance_variable_get(:@version)[0] + tomcat_version = instance.instance_variable_get(:@version)[0] components = [ instance, TomcatAccessLoggingSupport.new(sub_configuration_context(context, 'access_logging_support')), - TomcatGeodeStore.new(sub_configuration_context(context, 'geode_store')), + TomcatGeodeStore.new(sub_configuration_context(context, 'geode_store'), tomcat_version), TomcatInsightSupport.new(context), TomcatLifecycleSupport.new(sub_configuration_context(context, 'lifecycle_support')), TomcatLoggingSupport.new(sub_configuration_context(context, 'logging_support')), diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 765e9e7007..9b6d410611 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -27,6 +27,16 @@ module Container class TomcatGeodeStore < JavaBuildpack::Component::VersionedDependencyComponent include JavaBuildpack::Container + # Creates an instance. In addition to the functionality inherited from +VersionedDependencyComponent+ + # +@tomcat_version+ instance variable is exposed. + # + # @param [Hash] context a collection of utilities used by components + # @param [String] tomcat_version is the major version of tomcat + def initialize(context, tomcat_version) + super(context) + @tomcat_version = tomcat_version + end + # (see JavaBuildpack::Component::BaseComponent#compile) def compile return unless supports? @@ -144,16 +154,15 @@ def detect_geode_tomcat_version 'Please verify your geode_store tar contains a geode-modules-tomcat jar.') end - tomcat_version = @configuration['tomcat_version'] + puts " Detected Geode Tomcat #{geode_tomcat_version} module" # leave possibility for generic jar/session manager class that is compatible with all tomcat versions - if !geode_tomcat_version.empty? && geode_tomcat_version != tomcat_version - puts " WARNING: Tomcat version #{tomcat_version} " \ + if !geode_tomcat_version.empty? && geode_tomcat_version != @tomcat_version + puts " WARNING: Tomcat version #{@tomcat_version} " \ "does not match Geode Tomcat #{geode_tomcat_version} module. " \ 'If you encounter compatibility issues, please make sure these versions match.' end - puts " Detected Geode Tomcat #{geode_tomcat_version} module" @session_manager_classname = "org.apache.geode.modules.session.catalina.Tomcat#{geode_tomcat_version}DeltaSessionManager" end diff --git a/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml b/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml index e8c9e5e2ec..4dac5ae1c8 100644 --- a/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml +++ b/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml @@ -1,7 +1,7 @@ - - - diff --git a/spec/fixtures/stub-geode-store-tomcat8.tar b/spec/fixtures/stub-geode-store-tomcat8.tar deleted file mode 100644 index 945fffd43f5f3090c34acfbfdf57a437d32768d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30720 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 diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index d0e938cefc..034a2bf65a 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -62,13 +62,13 @@ it 'copies resources', app_fixture: 'container_tomcat_geode_store', - cache_fixture: 'stub-geode-store-tomcat8.tar' do + cache_fixture: 'stub-geode-store.tar' do component.compile expect(sandbox + 'lib/stub-jar-1.jar').to exist expect(sandbox + 'lib/stub-jar-2.jar').to exist - expect(sandbox + 'lib/geode-modules-tomcat8-1.13.0.jar').to exist + expect(sandbox + 'lib/geode-modules-tomcat9.jar').to exist end it 'mutates context.xml', @@ -94,16 +94,6 @@ ).to_stdout end - it 'correctly detects Geode Tomcat module version if different from default', - app_fixture: 'container_tomcat_geode_store', - cache_fixture: 'stub-geode-store-tomcat8.tar' do - - component.compile - - expect((sandbox + 'conf/context.xml').read) - .to eq(Pathname.new('spec/fixtures/container_tomcat8_geode_store_context_after.xml').read) - end - it 'does not add Geode Tomcat module version to Session Manager classname if version is empty', app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store-no-tomcat-version.tar' do From 5af13dcedbb0303a9a7e3ed2e8556a566547845d Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Fri, 26 Mar 2021 14:42:27 -0400 Subject: [PATCH 630/812] Polishing ADD_TO_CACHE * README updates * use commas to delimit components instead of colons Signed-off-by: Emily Casey --- README.md | 13 +++++++++++-- rakelib/dependency_cache_task.rb | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f1a2f68a74..89e7688390 100644 --- a/README.md +++ b/README.md @@ -157,12 +157,21 @@ Creating build/java-buildpack-cfd6b17.zip The offline package is a version of the buildpack designed to run without access to a network. It packages the latest version of each dependency (as configured in the [`config/` directory][]) and [disables `remote_downloads`][]. This package is about 180M in size. To create the offline package, use the `OFFLINE=true` argument: To pin the version of dependencies used by the buildpack to the ones currently resolvable use the `PINNED=true` argument. This will update the [`config/` directory][] to contain exact version of each dependency instead of version ranges. +```bash +$ bundle install +$ bundle exec rake clean package OFFLINE=true PINNED=true +... +Creating build/java-buildpack-offline-cfd6b17.zip +``` -Only packages referenced in the [`config/components.yml` file][] will be cached. Additional packages may be added using the `ADD_TO_CACHE` argument. It has to be set to the name of a `.yml` file in the [`config/` directory][]). Multiple file names may be separated by colons. This is useful to add additional JREs. +Only packages referenced in the [`config/components.yml` file](config/components.yml) will be cached. Additional packages may be added using the `ADD_TO_CACHE` argument. The value of `ADD_TO_CACHE` should be set to the name of a `.yml` file in the [`config/` directory][] with the `.yml` file extension omitted (e.g. `sap_machine_jre`). Multiple file names may be separated by commas. This is useful to add additional JREs. These additional components will not be enabled by default and must be explicitly enabled in the application with the `JBP_CONFIG_COMPONENTS` environment variable. ```bash $ bundle install -$ bundle exec rake clean package OFFLINE=true PINNED=true ADD_TO_CACHE=sap_machine_jre +$ bundle exec rake clean package OFFLINE=true ADD_TO_CACHE=sap_machine_jre,ibm_jre +... +Caching https://public.dhe.ibm.com/ibmdl/export/pub/systems/cloud/runtimes/java/8.0.6.26/linux/x86_64/ibm-java-jre-8.0-6.26-x86_64-archive.bin +Caching https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.10/sapmachine-jre-11.0.10_linux-x64_bin.tar.gz ... Creating build/java-buildpack-offline-cfd6b17.zip ``` diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 0535127a43..ad1b626d00 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -112,7 +112,7 @@ def component_ids conf = configuration('components').values.flatten.map { |component| component.split('::').last.snake_case } offline_cache = ENV['ADD_TO_CACHE'] if !offline_cache.nil? - offline_cache = offline_cache.split(':') + offline_cache = offline_cache.split(',') (conf << offline_cache).flatten!.uniq! end conf From 623c819842925d4a0d44d0b2bba3edd361e7dee9 Mon Sep 17 00:00:00 2001 From: Emily Casey Date: Fri, 26 Mar 2021 17:20:22 -0400 Subject: [PATCH 631/812] Fix rubocop offense Signed-off-by: Emily Casey --- rakelib/dependency_cache_task.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index ad1b626d00..7e600bde06 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -111,7 +111,7 @@ def cache_task(uri) def component_ids conf = configuration('components').values.flatten.map { |component| component.split('::').last.snake_case } offline_cache = ENV['ADD_TO_CACHE'] - if !offline_cache.nil? + unless offline_cache.nil? offline_cache = offline_cache.split(',') (conf << offline_cache).flatten!.uniq! end From b241ffa5cdc5d0b764907c78ff18a1b6a7a8d66c Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Wed, 7 Apr 2021 10:44:53 -0400 Subject: [PATCH 632/812] Add support for Datadog APM Javaagent Buildpack supporting the [Datadog Trace Agent](https://github.com/DataDog/datadog-cloudfoundry-buildpack) is not configured as a service binding, so we rely on detecting environment variable config for activation. --- config/components.yml | 1 + config/datadog_javaagent.yml | 19 +++++ docs/framework-datadog_javaagent.md | 40 +++++++++++ .../framework/datadog_javaagent.rb | 58 +++++++++++++++ rakelib/versions_task.rb | 1 + .../framework/datadog_javaagent_spec.rb | 71 +++++++++++++++++++ 6 files changed, 190 insertions(+) create mode 100644 config/datadog_javaagent.yml create mode 100644 docs/framework-datadog_javaagent.md create mode 100644 lib/java_buildpack/framework/datadog_javaagent.rb create mode 100644 spec/java_buildpack/framework/datadog_javaagent_spec.rb diff --git a/config/components.yml b/config/components.yml index 36161f4f6b..520549e914 100644 --- a/config/components.yml +++ b/config/components.yml @@ -49,6 +49,7 @@ frameworks: - "JavaBuildpack::Framework::ContainerCustomizer" - "JavaBuildpack::Framework::ContainerSecurityProvider" - "JavaBuildpack::Framework::ContrastSecurityAgent" + - "JavaBuildpack::Framework::DatadogJavaagent" - "JavaBuildpack::Framework::Debug" - "JavaBuildpack::Framework::DynatraceAppmonAgent" - "JavaBuildpack::Framework::DynatraceOneAgent" diff --git a/config/datadog_javaagent.yml b/config/datadog_javaagent.yml new file mode 100644 index 0000000000..ba5c97a322 --- /dev/null +++ b/config/datadog_javaagent.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2021 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Datadog APM Javaagent +--- +version: + +repository_root: https://raw.githubusercontent.com/datadog/dd-trace-java/cloudfoundry/ diff --git a/docs/framework-datadog_javaagent.md b/docs/framework-datadog_javaagent.md new file mode 100644 index 0000000000..8a6071941c --- /dev/null +++ b/docs/framework-datadog_javaagent.md @@ -0,0 +1,40 @@ +# Datadog APM Javaagent Framework +The [Datadog APM]() Javaagent Framework allows your application to be dynamically instrumented [by][datadog-javaagent] `dd-java-agent.jar`. + + + + + + + + + +
Detection CriterionOne of the following environment variables configured: +
    +
  • DD_APM_ENABLED configured as true
  • +
  • DD_API_KEY defined with the assumption of a datadog-cloudfoundry-buildpack configured, and DD_APM_ENABLED not false
  • +
+
Tagsdatadog-javaagent=<version>
+ +Tags are printed to standard output by the buildpack detect script + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. +The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +The javaagent can be configured directly via environment variables or system properties as defined in the [Configuration of Datadog Javaagent][] documentation. + + +| Name | Description +| ---- | ----------- +| `repository_root` | The URL of the Datadog Javaagent repository index ([details][repositories]). +| `version` | The `dd-java-agent` version to use. Candidate versions can be found in [this listing][]. + + +[Configuration and Extension]: ../README.md#configuration-and-extension +[Datadog APM]: https://www.datadoghq.com/product/apm/ +[datadog-javaagent]: https://github.com/datadog/dd-trace-java +[Configuration of Datadog Javaagent]: https://docs.datadoghq.com/tracing/setup_overview/setup/java/#configuration +[this listing]: https://raw.githubusercontent.com/datadog/dd-trace-java/cloudfoundry/index.yml +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/datadog_javaagent.rb b/lib/java_buildpack/framework/datadog_javaagent.rb new file mode 100644 index 0000000000..031817b883 --- /dev/null +++ b/lib/java_buildpack/framework/datadog_javaagent.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2021 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Elastic APM support. + class DatadogJavaagent < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + java_opts = @droplet.java_opts + java_opts.add_javaagent(@droplet.sandbox + jar_name) + + if !@application.environment.key?('DD_SERVICE') + java_opts.add_system_property('dd.service', @application.details['application_name']) + end + + if @application.details['application_version'] + java_opts.add_system_property('dd.version', @application.details['application_version']) + end + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + api_key_defined = @application.environment.key?('DD_API_KEY') && !@application.environment['DD_API_KEY'].empty? + apm_disabled = @application.environment['DD_APM_ENABLED'] == 'false' + apm_enabled = @application.environment['DD_APM_ENABLED'] == 'true' + (api_key_defined && !apm_disabled) || apm_enabled + end + end + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 8d88653145..88786d09a8 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -60,6 +60,7 @@ def initialize 'container_customizer' => 'Spring Boot Container Customizer', 'container_security_provider' => 'Container Security Provider', 'contrast_security_agent' => 'Contrast Security Agent', + 'datadog_javaagent' => 'Datadog APM Javaagent', 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', 'dynatrace_one_agent' => 'Dynatrace OneAgent', 'elastic_apm_agent' => 'Elastic APM Agent', diff --git a/spec/java_buildpack/framework/datadog_javaagent_spec.rb b/spec/java_buildpack/framework/datadog_javaagent_spec.rb new file mode 100644 index 0000000000..f150ec3c72 --- /dev/null +++ b/spec/java_buildpack/framework/datadog_javaagent_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2021 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/datadog_javaagent' +require 'java_buildpack/util/tokenized_version' + +describe JavaBuildpack::Framework::DatadogJavaagent do + include_context 'with component help' + + describe '#detect' do + subject(:detect) { component.detect } + + it 'does not detect without an api key' do + expect(detect).to be nil + end + + context 'when api key is empty' do + let(:environment) { { 'DD_API_KEY' => '' } } + + it { is_expected.to be nil } + end + + context 'when apm is disabled' do + let(:environment) { { 'DD_API_KEY' => 'foo', 'DD_APM_ENABLED' => 'false' } } + + it { is_expected.to be nil } + end + + context 'when apm is enabled with no api key' do + let(:environment) { { 'DD_APM_ENABLED' => 'true' } } + + it { is_expected.to eq("datadog-javaagent=#{version}") } + end + + context 'when apm key is provided' do + let(:environment) { { 'DD_API_KEY' => 'foo' } } + + it { is_expected.to eq("datadog-javaagent=#{version}") } + end + end + + context 'when apm key is provided' do + let(:environment) { { 'DD_API_KEY' => 'foo' } } + + it 'compile downloads datadog-javaagent JAR', cache_fixture: 'stub-datadog-javaagent.jar' do + component.compile + expect(sandbox + "datadog-javaagent-#{version}.jar").to exist + end + + it 'release updates JAVA_OPTS' do + component.release + expect(java_opts).to include("-javaagent:$PWD/.java-buildpack/datadog_javaagent/datadog_javaagent-#{version}.jar") + end + end +end From fc64d842da52e796363977992f650c4c6f2f145d Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 22 Apr 2021 14:31:44 -0400 Subject: [PATCH 633/812] Addressing feedback: - docs clarify relationship between agent & datadog buildpack - improves detection logic so it won't pass unless there is an API key and the datadog buildpack is present - updates docs to reflect new detection logic - docs added link to datadog docs that explains agent config --- .gitignore | 1 + docs/framework-datadog_javaagent.md | 20 ++++--- .../framework/datadog_javaagent.rb | 29 ++++++--- spec/fixtures/stub-datadog-javaagent.jar | Bin 0 -> 1288 bytes .../framework/datadog_javaagent_spec.rb | 55 +++++++++++++++--- .../util/configuration_utils_spec.rb | 2 +- 6 files changed, 82 insertions(+), 25 deletions(-) create mode 100644 spec/fixtures/stub-datadog-javaagent.jar diff --git a/.gitignore b/.gitignore index ad9e5451be..814b1fb86c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .yardoc build/ doc +.envrc diff --git a/docs/framework-datadog_javaagent.md b/docs/framework-datadog_javaagent.md index 8a6071941c..b5efa52f37 100644 --- a/docs/framework-datadog_javaagent.md +++ b/docs/framework-datadog_javaagent.md @@ -1,18 +1,23 @@ # Datadog APM Javaagent Framework -The [Datadog APM]() Javaagent Framework allows your application to be dynamically instrumented [by][datadog-javaagent] `dd-java-agent.jar`. +The [Datadog APM]() Javaagent Framework installs an agent that allows your application to be dynamically instrumented [by][datadog-javaagent] `dd-java-agent.jar`. + +For this functionality to work, you **must** also use this feature in combination with the [Datadog Cloudfoundry Buildpack](). The Datadog Cloudfoundry Buildpack **must** run first, so that it can supply the components to which the Datadog APM agent will talk. Please make sure you follow the instructions on the README for the Datadog Cloudfoundry Buildpack to enable and configure it. + +The framework will configure the Datadog agent for correct use in most situations, however you may adjust its behavior by setting additional environment variables. For a complete list of Datadog Agent configuration options, please see the [Datadog Documentation](https://docs.datadoghq.com/tracing/setup_overview/setup/java/?tab=containers#configuration). - - +
Detection CriterionOne of the following environment variables configured: -
    -
  • DD_APM_ENABLED configured as true
  • -
  • DD_API_KEY defined with the assumption of a datadog-cloudfoundry-buildpack configured, and DD_APM_ENABLED not false
  • -
+
Detection CriterionAll must be true: +
    +
  • The Datadog Buildpack must be included
  • +
  • DD_API_KEY defined and contain your API key
  • +
+ Optionally, you may set DD_APM_ENABLED to false to force the framework to not contribute the agent.
Tagsdatadog-javaagent=<version>datadog-javaagent=<version>
@@ -33,6 +38,7 @@ The javaagent can be configured directly via environment variables or system pro [Configuration and Extension]: ../README.md#configuration-and-extension [Datadog APM]: https://www.datadoghq.com/product/apm/ +[Datadog Cloudfoundry Builpack]: https://github.com/DataDog/datadog-cloudfoundry-buildpack [datadog-javaagent]: https://github.com/datadog/dd-trace-java [Configuration of Datadog Javaagent]: https://docs.datadoghq.com/tracing/setup_overview/setup/java/#configuration [this listing]: https://raw.githubusercontent.com/datadog/dd-trace-java/cloudfoundry/index.yml diff --git a/lib/java_buildpack/framework/datadog_javaagent.rb b/lib/java_buildpack/framework/datadog_javaagent.rb index 031817b883..69123af822 100644 --- a/lib/java_buildpack/framework/datadog_javaagent.rb +++ b/lib/java_buildpack/framework/datadog_javaagent.rb @@ -25,23 +25,35 @@ module Framework class DatadogJavaagent < JavaBuildpack::Component::VersionedDependencyComponent include JavaBuildpack::Util + def initialize(context) + super(context) + @datadog_buildpack = File.exist? File.join(@droplet.root, 'datadog') + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger DatadogJavaagent + end + # (see JavaBuildpack::Component::BaseComponent#compile) def compile - download_jar + @logger.error 'Datadog Buildpack is required, but not found' unless @datadog_buildpack + + download_jar if @datadog_buildpack end # (see JavaBuildpack::Component::BaseComponent#release) def release - java_opts = @droplet.java_opts + return unless @datadog_buildpack + + java_opts = @droplet.java_opts java_opts.add_javaagent(@droplet.sandbox + jar_name) - if !@application.environment.key?('DD_SERVICE') - java_opts.add_system_property('dd.service', @application.details['application_name']) + unless @application.environment.key?('DD_SERVICE') + app_name = @configuration['default_application_name'] || @application.details['application_name'] + java_opts.add_system_property('dd.service', "\\\"#{app_name}\\\"") end - if @application.details['application_version'] - java_opts.add_system_property('dd.version', @application.details['application_version']) - end + return unless @application.details['application_version'] + + version = @configuration['default_application_version'] || @application.details['application_version'] + java_opts.add_system_property('dd.version', version) end protected @@ -50,8 +62,7 @@ def release def supports? api_key_defined = @application.environment.key?('DD_API_KEY') && !@application.environment['DD_API_KEY'].empty? apm_disabled = @application.environment['DD_APM_ENABLED'] == 'false' - apm_enabled = @application.environment['DD_APM_ENABLED'] == 'true' - (api_key_defined && !apm_disabled) || apm_enabled + (api_key_defined && !apm_disabled) end end end diff --git a/spec/fixtures/stub-datadog-javaagent.jar b/spec/fixtures/stub-datadog-javaagent.jar new file mode 100644 index 0000000000000000000000000000000000000000..558673445672aa313d41c7168c02b9dbd42c653c GIT binary patch literal 1288 zcmWIWW@h1H00GuIdp9rxO0Y4=FeIj@=9TD&hHx@4uZ%t$5;@^)NNEK(10%~fMg|5J z5unNdoce{~`g1b#N-K0LEX;JxOo%j$1I;m#*bPH+-+EHrCx_3-I=2Urn z=H_H3!NOoSAqS%ytV7sfpz$ds;6TwU&Id;u$QBUB8ExWoP@^3bERp%8!5R6bIVpbm zB_4@osiApQnFR%@DZZ(CB^4!LbA5qH0faHkWn_|L#+9HXph-)B;jJTx35z~fNb(}V zEMW#@vmD@Np(QoK24f~PWP^LL8;s;`P_iSz-Et`Iet^$-Xc8ps1@v?xk79=fFsDM? zixM_4AxLrrT7or^AR-gp5*@fD3=B&eCla;_E7fiGjf%h#43FCtUvH literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/datadog_javaagent_spec.rb b/spec/java_buildpack/framework/datadog_javaagent_spec.rb index f150ec3c72..bc3b8074ca 100644 --- a/spec/java_buildpack/framework/datadog_javaagent_spec.rb +++ b/spec/java_buildpack/framework/datadog_javaagent_spec.rb @@ -23,6 +23,11 @@ describe JavaBuildpack::Framework::DatadogJavaagent do include_context 'with component help' + let(:configuration) do + { 'default_application_version' => nil, + 'default_application_name' => nil } + end + describe '#detect' do subject(:detect) { component.detect } @@ -45,7 +50,7 @@ context 'when apm is enabled with no api key' do let(:environment) { { 'DD_APM_ENABLED' => 'true' } } - it { is_expected.to eq("datadog-javaagent=#{version}") } + it { is_expected.to be nil } end context 'when apm key is provided' do @@ -56,16 +61,50 @@ end context 'when apm key is provided' do - let(:environment) { { 'DD_API_KEY' => 'foo' } } + let(:environment) do + super().update({ 'DD_API_KEY' => 'foo' }) + end - it 'compile downloads datadog-javaagent JAR', cache_fixture: 'stub-datadog-javaagent.jar' do - component.compile - expect(sandbox + "datadog-javaagent-#{version}.jar").to exist + context 'when datadog buildpack is present' do + before do + FileUtils.mkdir_p File.join(context[:droplet].root, 'datadog') + end + + after do + FileUtils.rmdir File.join(context[:droplet].root, 'datadog') + end + + it 'compile downloads datadog-javaagent JAR', cache_fixture: 'stub-datadog-javaagent.jar' do + component.compile + expect(sandbox + "datadog_javaagent-#{version}.jar").to exist + end + + it 'release updates JAVA_OPTS' do + component.release + + expect(java_opts).to include( + "-javaagent:$PWD/.java-buildpack/datadog_javaagent/datadog_javaagent-#{version}.jar" + ) + expect(java_opts).to include('-Ddd.service=\"test-application-name\"') + expect(java_opts).to include('-Ddd.version=test-application-version') + end end - it 'release updates JAVA_OPTS' do - component.release - expect(java_opts).to include("-javaagent:$PWD/.java-buildpack/datadog_javaagent/datadog_javaagent-#{version}.jar") + context 'when datadog buildpack is not present' do + it 'compile downloads datadog-javaagent JAR', cache_fixture: 'stub-datadog-javaagent.jar' do + component.compile + expect(sandbox + "datadog_javaagent-#{version}.jar").not_to exist + end + + it 'release updates JAVA_OPTS' do + component.release + + expect(java_opts).not_to include( + "-javaagent:$PWD/.java-buildpack/datadog_javaagent/datadog_javaagent-#{version}.jar" + ) + expect(java_opts).not_to include('-Ddd.service=\"test-application-name\"') + expect(java_opts).not_to include('-Ddd.version=test-application-version') + end end end end diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 63f352b55e..91fc98dcc6 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -115,7 +115,7 @@ context do let(:environment) do - { 'JBP_CONFIG_TEST' => '{version:1.8.+}' } + { 'JBP_CONFIG_TEST' => '{version: 1.8.+' } end it 'diagnoses invalid YAML syntax' do From 906044b7cbcb13920496a35750a549a7bf5d9ccb Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 5 May 2021 11:44:28 -0400 Subject: [PATCH 634/812] Adjust the way arguments are being escaped. (#870) Adjusts the way App Dynamics configuration properties are being escaped. They are passed into the JVM process via system properties, so the values require proper escaping or they can cause issues. This PR uses `Shellwords.escape` to perform the escaping of the configuration set at build time. Values that are selected at runtime before an app starts are escaped at that point in time (using `jq`'s `@sh`), so those are *not* escaped at build time otherwise it results in double escaping of those values (like seeing `'`'s in the app name). This PR also updates the docs as the set of required properties for the App Dynamic agent have changed. --- config/app_dynamics_agent.yml | 4 +-- docs/framework-app_dynamics_agent.md | 14 ++++---- .../framework/app_dynamics_agent.rb | 29 +++++++++++----- .../framework/app_dynamics_agent_spec.rb | 34 ++++++++++++++++--- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index 69b2b1f9f4..c898bcdfef 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -18,6 +18,6 @@ version: + repository_root: https://packages.appdynamics.com/java default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") -default_node_name: $(jq -r -n "\"$APPD_CF_NODE_PREFIX\" + ($VCAP_APPLICATION | .application_name) + \":$CF_INSTANCE_INDEX\"") +default_node_name: $(jq -r -n "\"$APPD_CF_NODE_PREFIX\" + ($VCAP_APPLICATION | .application_name) + \":$CF_INSTANCE_INDEX\" | @sh") default_tier_name: -default_unique_host_name: $(jq -r -n "$VCAP_APPLICATION | .application_id + \":$CF_INSTANCE_INDEX\"") +default_unique_host_name: $(jq -r -n "$VCAP_APPLICATION | .application_id + \":$CF_INSTANCE_INDEX\" | @sh") diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 4a700dfcb8..7a74a0d3c4 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -13,21 +13,23 @@ The AppDynamics Agent Framework causes an application to be automatically config Tags are printed to standard output by the buildpack detect script ## User-Provided Service -When binding AppDynamics using a user-provided service, it must have name or tag with `app-dynamics` or `appdynamics` in it. The credential payload can contain the following entries. **Note:** Credentials marked as "(Optional)" may be required for some versions of the AppDynamics agent. Please see the [AppDynamics Java Agent Configuration Properties][] for the version of the agent used by your application for more details. +When binding AppDynamics using a user-provided service, it must have name or tag with `app-dynamics` or `appdynamics` in it. The credential payload can contain the following entries. | Name | Description | ---- | ----------- -| `account-access-key` | (Optional) The account access key to use when authenticating with the controller -| `account-name` | (Optional) The account name to use when authenticating with the controller -| `application-name` | (Optional) the application's name +| `account-access-key` | The account access key to use when authenticating with the controller +| `account-name` | The account name to use when authenticating with the controller | `host-name` | The controller host name +| `port` | The controller port +| `ssl-enabled` | Whether or not to use an SSL connection to the controller +| `application-name` | (Optional) the application's name | `node-name` | (Optional) the application's node name -| `port` | (Optional) The controller port -| `ssl-enabled` | (Optional) Whether or not to use an SSL connection to the controller | `tier-name` | (Optional) the application's tier name To provide more complex values such as the `tier-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `tier-name` could be set with a value of `Tier-$(expr "$VCAP_APPLICATION" : '.*instance_index[": ]*\([[:digit:]]*\).*')` to calculate a value from the Cloud Foundry instance index. +**Note:** Some credentials were previously marked as "(Optional)" as requirements have changed across versions of the AppDynamics agent. Please see the [AppDynamics Java Agent Configuration Properties][] for the version of the agent used by your application for more details. + ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index ed763db979..9e21b7510b 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -16,6 +16,7 @@ # limitations under the License. require 'fileutils' +require 'shellwords' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' @@ -79,30 +80,36 @@ def supports? private_constant :CONFIG_FILES, :FILTER def application_name(java_opts, credentials) - name = credentials['application-name'] || @configuration['default_application_name'] || - @application.details['application_name'] - java_opts.add_system_property('appdynamics.agent.applicationName', "\\\"#{name}\\\"") + name = Shellwords.escape(@application.details['application_name']) + name = @configuration['default_application_name'] if @configuration['default_application_name'] + name = Shellwords.escape(credentials['application-name']) if credentials['application-name'] + + java_opts.add_system_property('appdynamics.agent.applicationName', name.to_s) end def account_access_key(java_opts, credentials) account_access_key = credentials['account-access-key'] || credentials.dig('account-access-secret', 'secret') + account_access_key = Shellwords.escape(account_access_key) + java_opts.add_system_property 'appdynamics.agent.accountAccessKey', account_access_key if account_access_key end def account_name(java_opts, credentials) account_name = credentials['account-name'] - java_opts.add_system_property 'appdynamics.agent.accountName', account_name if account_name + java_opts.add_system_property 'appdynamics.agent.accountName', Shellwords.escape(account_name) if account_name end def host_name(java_opts, credentials) host_name = credentials['host-name'] raise "'host-name' credential must be set" unless host_name - java_opts.add_system_property 'appdynamics.controller.hostName', host_name + java_opts.add_system_property 'appdynamics.controller.hostName', Shellwords.escape(host_name) end def node_name(java_opts, credentials) - name = credentials['node-name'] || @configuration['default_node_name'] + name = @configuration['default_node_name'] + name = Shellwords.escape(credentials['node-name']) if credentials['node-name'] + java_opts.add_system_property('appdynamics.agent.nodeName', name.to_s) end @@ -117,13 +124,17 @@ def ssl_enabled(java_opts, credentials) end def tier_name(java_opts, credentials) - name = credentials['tier-name'] || @configuration['default_tier_name'] || - @application.details['application_name'] + name = Shellwords.escape(@application.details['application_name']) + name = @configuration['default_tier_name'] if @configuration['default_tier_name'] + name = Shellwords.escape(credentials['tier-name']) if credentials['tier-name'] + java_opts.add_system_property('appdynamics.agent.tierName', name.to_s) end def unique_host_name(java_opts) - name = @configuration['default_unique_host_name'] || @application.details['application_name'] + name = @configuration['default_unique_host_name'] + name = Shellwords.escape(@application.details['application_name']) if @application.details['application_name'] + java_opts.add_system_property('appdynamics.agent.uniqueHostId', name.to_s) end diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index ac981959a6..f8f988d567 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -66,7 +66,7 @@ expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/app_dynamics_agent/javaagent.jar') expect(java_opts).to include('-Dappdynamics.controller.hostName=test-host-name') - expect(java_opts).to include('-Dappdynamics.agent.applicationName=\"test-application-name\"') + expect(java_opts).to include('-Dappdynamics.agent.applicationName=test-application-name') expect(java_opts).to include('-Dappdynamics.agent.tierName=test-application-name') expect(java_opts).to include('-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : ' \ '\'.*instance_index[": ]*\\([[:digit:]]*\\).*\')') @@ -83,12 +83,38 @@ end context do - let(:credentials) { super().merge 'application-name' => 'another-test-application-name' } + let(:credentials) { super().merge 'tier-name' => 'another-test tier-name' } - it 'adds application_name from credentials to JAVA_OPTS if specified' do + it 'adds tier_name from credentials with space in name to JAVA_OPTS if specified' do component.release - expect(java_opts).to include('-Dappdynamics.agent.applicationName=\"another-test-application-name\"') + expect(java_opts).to include('-Dappdynamics.agent.tierName=another-test\ tier-name') + end + end + + context do + let(:credentials) { super().merge 'application-name' => 'another-test application-name' } + + it 'adds application_name from credentials with space in name to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dappdynamics.agent.applicationName=another-test\ application-name') + end + end + + context do + let(:configuration) do + { 'default_tier_name' => nil, + 'default_node_name' => nil, + 'default_application_name' => 'default application-name' } + end + + it 'adds application_name from default config to JAVA_OPTS if specified' do + component.release + + # should not be escaped, escaping happens at runtime because default value is a sub-command + # executed in the runtime container + expect(java_opts).to include('-Dappdynamics.agent.applicationName=default application-name') end end From 01d934564dba5b604982606060a1a535ba620b06 Mon Sep 17 00:00:00 2001 From: Alon Weiss Date: Wed, 19 May 2021 18:27:10 +0300 Subject: [PATCH 635/812] Implement Sealights Agent framework (#873) Add Sealights Agent framework --- config/components.yml | 1 + config/sealights_agent.yml | 23 ++++ docs/framework-sealights_agent.md | 48 +++++++ .../framework/sealights_agent.rb | 87 +++++++++++++ rakelib/versions_task.rb | 1 + .../framework/sealights_agent_spec.rb | 119 ++++++++++++++++++ 6 files changed, 279 insertions(+) create mode 100644 config/sealights_agent.yml create mode 100644 docs/framework-sealights_agent.md create mode 100644 lib/java_buildpack/framework/sealights_agent.rb create mode 100644 spec/java_buildpack/framework/sealights_agent_spec.rb diff --git a/config/components.yml b/config/components.yml index 520549e914..e7e6c39230 100644 --- a/config/components.yml +++ b/config/components.yml @@ -69,6 +69,7 @@ frameworks: - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::ProtectAppSecurityProvider" - "JavaBuildpack::Framework::RiverbedAppinternalsAgent" + - "JavaBuildpack::Framework::SealightsAgent" - "JavaBuildpack::Framework::SeekerSecurityProvider" - "JavaBuildpack::Framework::SpringAutoReconfiguration" - "JavaBuildpack::Framework::SpringInsight" diff --git a/config/sealights_agent.yml b/config/sealights_agent.yml new file mode 100644 index 0000000000..a75881a853 --- /dev/null +++ b/config/sealights_agent.yml @@ -0,0 +1,23 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the SeaLights Agent framework +--- +version: + +repository_root: https://agents.sealights.co/pcf +build_session_id: +lab_id: +proxy: +auto_upgrade: false diff --git a/docs/framework-sealights_agent.md b/docs/framework-sealights_agent.md new file mode 100644 index 0000000000..7ad8f2d229 --- /dev/null +++ b/docs/framework-sealights_agent.md @@ -0,0 +1,48 @@ +# Sealights Agent Framework +The Sealights Agent Framework causes an application to be automatically configured to work with [Sealights Service][]. + + + + + + + + +
Detection CriterionExistence of a single bound sealights service. The existence of a sealights service defined by the VCAP_SERVICES payload containing a service name, label or tag with sealights as a substring. +
Tagssealights-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +When binding Sealights using a user-provided service, it must have name or tag with `sealights` in it. +The credential payload can contain the following entries. + +| Name | Description +| ---- | ----------- +| `token` | A Sealights Agent token + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The framework can be configured by modifying the [`config/sealights_agent.yml`][] file. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. + +| Name | Description +| ---- | ----------- +| `build_session_id` | Sealights [Build Session ID][] for the application. Leave blank to use the value embedded in the jar/war artifacts +| `proxy` | Specify a HTTP proxy used to communicate with the Sealights backend. Used when the corporate network prohibits communication to cloud services by default. +| `lab_id` | Specify a Sealights [Lab ID][] +| `auto_upgrade` | Enable/disable agent auto-upgrade. Off by default +| `version` | The version of Auto-reconfiguration to use. Candidate versions can be found in [this listing][]. If auto_upgrade is turned on, a different version may be downloaded and used at runtime + +## Troubleshooting and Support + +For additional documentation and support, visit the official [Sealights Java agents documentation] page + +[`config/sealights_agent.yml`]: ../config/sealights_agent.yml +[Configuration and Extension]: ../README.md#configuration-and-extension +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering +[Sealights Service]: https://www.sealights.io +[Build Session ID]: https://sealights.atlassian.net/wiki/spaces/SUP/pages/3473472/Using+Java+Agents+-+Generating+a+session+ID +[Lab ID]: https://sealights.atlassian.net/wiki/spaces/SUP/pages/762413124/Using+Java+Agents+-+Running+Tests+in+Parallel+Lab+Id +[this listing]: https://agents.sealights.co/pcf/index.yml +[Sealights Java agents documentation]: https://sealights.atlassian.net/wiki/spaces/SUP/pages/3014685/SeaLights+Java+agents diff --git a/lib/java_buildpack/framework/sealights_agent.rb b/lib/java_buildpack/framework/sealights_agent.rb new file mode 100644 index 0000000000..0bd2cd42cf --- /dev/null +++ b/lib/java_buildpack/framework/sealights_agent.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/framework' +require 'java_buildpack/component/versioned_dependency_component' +require 'shellwords' +require 'fileutils' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for enabling zero-touch Sealights support. + class SealightsAgent < JavaBuildpack::Component::VersionedDependencyComponent + # include JavaBuildpack::Util + + def initialize(context) + super(context) + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger SealightsAgent + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_zip(false) + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts.add_javaagent(agent) + credentials = @application.services.find_service(FILTER, TOKEN)['credentials'] + @droplet.java_opts.add_system_property('sl.token', Shellwords.escape(credentials[TOKEN])) + @droplet.java_opts.add_system_property('sl.tags', 'pivotal_cloud_foundry') + add_system_property 'sl.enableUpgrade', ENABLE_UPGRADE + add_system_property 'sl.buildSessionId', BUILD_SESSION_ID + add_system_property 'sl.proxy', PROXY + add_system_property 'sl.labId', LAB_ID + end + + def add_system_property(system_property, config_key) + return unless @configuration.key?(config_key) + + @droplet.java_opts.add_system_property(system_property, Shellwords.escape(@configuration[config_key])) + end + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, TOKEN + end + + private + + def agent + @droplet.sandbox + "sl-test-listener-#{@version}.jar" + end + + # Configuration property names + TOKEN = 'token' + + ENABLE_UPGRADE = 'enable_upgrade' + + BUILD_SESSION_ID = 'build_session_id' + + LAB_ID = 'lab_id' + + PROXY = 'proxy' + + FILTER = /sealights/.freeze + + private_constant :TOKEN, :ENABLE_UPGRADE, :BUILD_SESSION_ID, :LAB_ID, :PROXY, :FILTER + + end + + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 88786d09a8..ebc7313d98 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -87,6 +87,7 @@ def initialize 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', 'redis_store' => 'Redis Session Store', 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', + 'sealights_agent' => 'SeaLights Agent', 'sky_walking_agent' => 'SkyWalking', 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', 'spring_boot_cli' => 'Spring Boot CLI', diff --git a/spec/java_buildpack/framework/sealights_agent_spec.rb b/spec/java_buildpack/framework/sealights_agent_spec.rb new file mode 100644 index 0000000000..b85ce66f56 --- /dev/null +++ b/spec/java_buildpack/framework/sealights_agent_spec.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/sealights_agent' +require 'java_buildpack/util/tokenized_version' + +describe JavaBuildpack::Framework::SealightsAgent do + include_context 'with component help' + + it 'does not detect without sealights service' do + expect(component.detect).to be_nil + end + + context do + + let(:credentials) { { 'token' => 'my_token' } } + + let(:configuration) do + { 'build_session_id' => '1234', + 'proxy' => '127.0.0.1:8888', + 'lab_id' => 'lab1', + 'enable_upgrade' => true } + end + + before do + allow(services).to receive(:one_service?).with(/sealights/, 'token').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => credentials) + end + + it 'detects with sealights service' do + expect(component.detect).to eq("sealights-agent=#{version}") + end + + context do + it 'updates JAVA_OPTS sl.tags' do + component.release + + expect(java_opts).to include('-Dsl.tags=pivotal_cloud_foundry') + end + + it 'updates JAVA_OPTS sl.buildSessionId' do + component.release + + expect(java_opts).to include("-Dsl.buildSessionId=#{configuration['build_session_id']}") + end + + it 'updates JAVA_OPTS sl.labId' do + component.release + + expect(java_opts).to include("-Dsl.labId=#{configuration['lab_id']}") + end + + it 'updates JAVA_OPTS sl.proxy' do + component.release + + expect(java_opts).to include("-Dsl.proxy=#{configuration['proxy']}") + end + + it 'updates JAVA_OPTS sl.enableUpgrade' do + component.release + + expect(java_opts).to include("-Dsl.enableUpgrade=#{configuration['enable_upgrade']}") + end + + it 'updates JAVA_OPTS sl.token' do + component.release + + expect(java_opts).to include("-Dsl.token=#{credentials['token']}") + end + end + + context do + let(:configuration) { {} } + + it 'does not specify JAVA_OPTS sl.buildSessionId if one was not specified' do + component.release + + expect(java_opts).not_to include(/buildSessionId/) + end + + it 'does not specify JAVA_OPTS sl.labId if one was not specified' do + component.release + + expect(java_opts).not_to include(/labId/) + end + + it 'does not specify JAVA_OPTS sl.proxy if one was not specified' do + component.release + + expect(java_opts).not_to include(/proxy/) + end + + it 'does not specify JAVA_OPTS sl.enableUpgrade if one was not specified' do + component.release + + expect(java_opts).not_to include(/enableUpgrade/) + end + + end + + end + +end From 34cda928fcabb3770b970311612fed66e087df28 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 19 May 2021 11:41:57 -0400 Subject: [PATCH 636/812] Polishing --- docs/framework-sealights_agent.md | 2 +- lib/java_buildpack/framework/sealights_agent.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/framework-sealights_agent.md b/docs/framework-sealights_agent.md index 7ad8f2d229..7b3cf524d4 100644 --- a/docs/framework-sealights_agent.md +++ b/docs/framework-sealights_agent.md @@ -28,7 +28,7 @@ The framework can be configured by modifying the [`config/sealights_agent.yml`][ | Name | Description | ---- | ----------- | `build_session_id` | Sealights [Build Session ID][] for the application. Leave blank to use the value embedded in the jar/war artifacts -| `proxy` | Specify a HTTP proxy used to communicate with the Sealights backend. Used when the corporate network prohibits communication to cloud services by default. +| `proxy` | Specify a HTTP proxy used to communicate with the Sealights backend. Required when a corporate network prohibits communication to cloud services. The default is to have no proxy configured. This does not inherit from `http_proxy`/`https_proxy` or `http.proxyHost/https.proxyHost`, you must set this specifically if a proxy is needed. | `lab_id` | Specify a Sealights [Lab ID][] | `auto_upgrade` | Enable/disable agent auto-upgrade. Off by default | `version` | The version of Auto-reconfiguration to use. Candidate versions can be found in [this listing][]. If auto_upgrade is turned on, a different version may be downloaded and used at runtime diff --git a/lib/java_buildpack/framework/sealights_agent.rb b/lib/java_buildpack/framework/sealights_agent.rb index 0bd2cd42cf..c40e034fc9 100644 --- a/lib/java_buildpack/framework/sealights_agent.rb +++ b/lib/java_buildpack/framework/sealights_agent.rb @@ -49,6 +49,7 @@ def release add_system_property 'sl.labId', LAB_ID end + # wrapper for setting system properties on the droplet from configuration keys def add_system_property(system_property, config_key) return unless @configuration.key?(config_key) From a857384cfe72a32c7c577d61cbdf3a55a077c6cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 May 2021 11:44:49 -0400 Subject: [PATCH 637/812] Bump redcarpet from 3.5.0 to 3.5.1 (#876) Bumps [redcarpet](https://github.com/vmg/redcarpet) from 3.5.0 to 3.5.1. - [Release notes](https://github.com/vmg/redcarpet/releases) - [Changelog](https://github.com/vmg/redcarpet/blob/master/CHANGELOG.md) - [Commits](https://github.com/vmg/redcarpet/compare/v3.5.0...v3.5.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d35bd7eb4f..5ad5c5a204 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,7 +15,7 @@ GEM public_suffix (4.0.4) rainbow (3.0.0) rake (13.0.1) - redcarpet (3.5.0) + redcarpet (3.5.1) rexml (3.2.4) rspec (3.9.0) rspec-core (~> 3.9.0) From f3cdfc5a0bcfd4fac1d3a503d7993d9dd9b3602a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 May 2021 11:45:33 -0400 Subject: [PATCH 638/812] Bump rexml from 3.2.4 to 3.2.5 (#877) Bumps [rexml](https://github.com/ruby/rexml) from 3.2.4 to 3.2.5. - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.2.4...v3.2.5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Mikusa --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5ad5c5a204..5d0222e4c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,8 +15,8 @@ GEM public_suffix (4.0.4) rainbow (3.0.0) rake (13.0.1) + rexml (3.2.5) redcarpet (3.5.1) - rexml (3.2.4) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) From 751b4536854458776ce7de62e18ed013abf3fe71 Mon Sep 17 00:00:00 2001 From: Alon Weiss Date: Thu, 20 May 2021 15:49:26 +0300 Subject: [PATCH 639/812] Added Sealights Framework to readme.md (#878) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 89e7688390..c0ed3b1fb2 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ The buildpack supports extension through the use of Git repository forking. The * [PostgreSQL JDBC](docs/framework-postgresql_jdbc.md) ([Configuration](docs/framework-postgresql_jdbc.md#configuration)) * [ProtectApp Security Provider](docs/framework-protect_app_security_provider.md) ([Configuration](docs/framework-protect_app_security_provider.md#configuration)) * [Riverbed AppInternals Agent](docs/framework-riverbed_appinternals_agent.md) ([Configuration](docs/framework-riverbed_appinternals_agent.md#configuration)) + * [Sealights Agent](docs/framework-sealights_agent.md) ([Configuration](docs/framework-sealights_agent.md#configuration)) * [Seeker Security Provider](docs/framework-seeker_security_provider.md) ([Configuration](docs/framework-seeker_security_provider.md#configuration)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) * [Spring Insight](docs/framework-spring_insight.md) From 6bb323dff2d87465208eb3657f6da4f7e262cd9d Mon Sep 17 00:00:00 2001 From: Martin Pfeifer Date: Wed, 26 May 2021 15:50:28 +0200 Subject: [PATCH 640/812] Don't set dd.version Java opts if DD_VERSION env var is provided --- lib/java_buildpack/framework/datadog_javaagent.rb | 2 +- .../framework/datadog_javaagent_spec.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/datadog_javaagent.rb b/lib/java_buildpack/framework/datadog_javaagent.rb index 69123af822..a5a88d3916 100644 --- a/lib/java_buildpack/framework/datadog_javaagent.rb +++ b/lib/java_buildpack/framework/datadog_javaagent.rb @@ -50,7 +50,7 @@ def release java_opts.add_system_property('dd.service', "\\\"#{app_name}\\\"") end - return unless @application.details['application_version'] + return if @application.environment.key?('DD_VERSION') || !@application.details['application_version'] version = @configuration['default_application_version'] || @application.details['application_version'] java_opts.add_system_property('dd.version', version) diff --git a/spec/java_buildpack/framework/datadog_javaagent_spec.rb b/spec/java_buildpack/framework/datadog_javaagent_spec.rb index bc3b8074ca..6e39d57bc0 100644 --- a/spec/java_buildpack/framework/datadog_javaagent_spec.rb +++ b/spec/java_buildpack/framework/datadog_javaagent_spec.rb @@ -107,4 +107,16 @@ end end end + + context 'when dd_version environment variable is provided' do + let(:environment) do + super().update({ 'DD_VERSION' => 'test-application-version' }) + end + + it 'release updates JAVA_OPTS' do + component.release + + expect(java_opts).not_to include('-Ddd.version=test-application-version') + end + end end From f66db372fa55ac35f453d1b027d5b75aa8f33cf9 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 26 May 2021 10:35:39 -0400 Subject: [PATCH 641/812] Adds external configuration support for Luna Security Module (#879) - Extracts external configuration code into a utility - Modifies AppDynamics to use the utility code - Modifies Luna Security Provider to use the utility code - Updates documentation for AppDynamics and Luna to explaini how external configuration works --- Gemfile.lock | 4 +- docs/framework-app_dynamics_agent.md | 46 +++++- docs/framework-luna_security_provider.md | 22 ++- .../framework/app_dynamics_agent.rb | 89 +++-------- .../framework/luna_security_provider.rb | 45 +++++- lib/java_buildpack/util/external_config.rb | 92 +++++++++++ .../framework/luna_security_provider_spec.rb | 145 ++++++++++++++++++ 7 files changed, 364 insertions(+), 79 deletions(-) create mode 100644 lib/java_buildpack/util/external_config.rb diff --git a/Gemfile.lock b/Gemfile.lock index 5d0222e4c3..689eda08b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,8 +15,8 @@ GEM public_suffix (4.0.4) rainbow (3.0.0) rake (13.0.1) - rexml (3.2.5) redcarpet (3.5.1) + rexml (3.2.5) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) @@ -69,4 +69,4 @@ DEPENDENCIES yard BUNDLED WITH - 2.1.4 + 2.2.16 diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 7a74a0d3c4..c0f76c135c 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -44,7 +44,51 @@ The framework can be configured by modifying the [`config/app_dynamics_agent.yml | `version` | The version of AppDynamics to use. Candidate versions can be found in [this listing][]. ### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/app_dynamics_agent` directory in the buildpack fork. For example, to override the default `app-agent-config.xml` add your custom file to `resources/app_dynamics_agent//conf/app-agent-config.xml`. +The framework can also be configured by overlaying a set of resources on the default distribution. To do this follow one of the options below. + +Configuration files are created in this order: + +1. Default AppDynamics configuration +2. Buildpack default configuration is taken from `resources/app_dynamics_agent/default` +3. External Configuration if configured +4. Local Configuration if configured +5. Buildpack Fork if it exists + +#### Buildpack Fork +Add files to the `resources/app_dynamics_agent` directory in the buildpack fork. For example, to override the default `app-agent-config.xml` add your custom file to `resources/app_dynamics_agent//conf/app-agent-config.xml`. + +#### External Configuration +Set `APPD_CONF_HTTP_URL` to an HTTP or HTTPS URL which points to the directory where your configuration files exist. You may also include a user and password in the URL, like `https://user:pass@example.com`. + +The Java buildpack will take the URL to the directory provided and attempt to download the following files from that directory: + +- `logging/log4j2.xml` +- `logging/log4j.xml` +- `app-agent-config.xml` +- `controller-info.xml` +- `service-endpoint.xml` +- `transactions.xml` +- `custom-interceptors.xml` +- `custom-activity-correlation.xml` + +Any file successfully downloaded will be copied to the configuration directory. The buildpack does not fail if files are missing. + +#### Local Configuration +Set `APPD_CONF_DIR` to a relative path which points to the directory in your application files where your custom configuration exists. + +The Java buildpack will take the `app_root` + `APPD_CONF_DIR` directory and attempt to copy the followinig files from that directory: + +- `logging/log4j2.xml` +- `logging/log4j.xml` +- `app-agent-config.xml` +- `controller-info.xml` +- `service-endpoint.xml` +- `transactions.xml` +- `custom-interceptors.xml` +- `custom-activity-correlation.xml` + +Any files that exist will be copied to the configuration directory. The buildpack does not fail if files are missing. + [`config/app_dynamics_agent.yml`]: ../config/app_dynamics_agent.yml [AppDynamics Java Agent Configuration Properties]: https://docs.appdynamics.com/display/PRO42/Java+Agent+Configuration+Properties diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md index a749dedfb6..7fd8ad0cda 100644 --- a/docs/framework-luna_security_provider.md +++ b/docs/framework-luna_security_provider.md @@ -98,7 +98,27 @@ The framework can be configured by modifying the [`config/luna_security_provider | `version` | Version of the Luna Security Provider to use. ### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/luna_security_provider` directory in the buildpack fork. +The framework can also be configured by overlaying a set of resources on the default distribution. To do this follow one of the options below. + +Configuration files are created in this order: + +1. Default configuration +2. Buildpack fork +3. Buildpack generated configuration if the bound service has both a `servers` and `groups` key +4. External configuration if configured + +#### Buildpack Fork +Add files to the `resources/luna_security_provider` directory in the buildpack fork. For example, to override the default `Chrystoki.conf` add your custom file to `resources/luna_security_provider/Chrystoki.conf`. + +#### External Configuration +Set `LUNA_CONF_HTTP_URL` to an HTTP or HTTPS URL which points to the directory where your configuration files exist. You may also include a user and password in the URL, like `https://user:pass@example.com`. + +The Java buildpack will take the URL to the directory provided and attempt to download the following files from that directory: + +- `Chrystoki.conf` +- `server-certificates.pem` + +Any file successfully downloaded will be copied to the configuration directory. The buildpack does not fail if files are missing. [`config/luna_security_provider.yml`]: ../config/luna_security_provider.yml [Luna Security Service]: http://www.safenet-inc.com/data-encryption/hardware-security-modules-hsms/ diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 9e21b7510b..545ff70daa 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -19,12 +19,22 @@ require 'shellwords' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' +require 'java_buildpack/util/external_config' module JavaBuildpack module Framework # Encapsulates the functionality for enabling zero-touch AppDynamics support. class AppDynamicsAgent < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util::ExternalConfig + + # Full list of configuration files that can be downloaded remotely + CONFIG_FILES = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml + service-endpoint.xml transactions.xml custom-interceptors.xml + custom-activity-correlation.xml].freeze + + # Prefix to be used with external configuration environment variable + CONFIG_PREFIX = 'APPD' def initialize(context) super(context) @@ -40,7 +50,7 @@ def compile default_conf_dir = resources_dir + @droplet.component_id + 'defaults' copy_appd_default_configuration(default_conf_dir) - override_default_config_remote + override_default_config_remote(&method(:save_cfg_file)) override_default_config_local @droplet.copy_resources end @@ -71,13 +81,9 @@ def supports? private - CONFIG_FILES = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml - service-endpoint.xml transactions.xml custom-interceptors.xml - custom-activity-correlation.xml].freeze - FILTER = /app[-]?dynamics/.freeze - private_constant :CONFIG_FILES, :FILTER + private_constant :FILTER def application_name(java_opts, credentials) name = Shellwords.escape(@application.details['application_name']) @@ -150,67 +156,6 @@ def copy_appd_default_configuration(default_conf_dir) end end - # Check if configuration file exists on the server before download - # @param [ResourceURI] uri URI of the remote configuration server - # @param [ConfigFileName] conf_file Name of the configuration file - # @return [Boolean] returns true if files exists on path specified by APPD_CONF_HTTP_URL, false otherwise - def check_if_resource_exists(resource_uri, conf_file) - # check if resource exists on remote server - begin - opts = { use_ssl: true } if resource_uri.scheme == 'https' - response = Net::HTTP.start(resource_uri.host, resource_uri.port, opts) do |http| - req = Net::HTTP::Head.new(resource_uri) - if resource_uri.user != '' || resource_uri.password != '' - req.basic_auth(resource_uri.user, resource_uri.password) - end - http.request(req) - end - rescue StandardError => e - @logger.error { "Request failure: #{e.message}" } - return false - end - - case response - when Net::HTTPSuccess - true - when Net::HTTPRedirection - location = response['location'] - @logger.info { "redirected to #{location}" } - check_if_resource_exists(location, conf_file) - else - @logger.info { "Could not retrieve #{resource_uri}. Code: #{response.code} Message: #{response.message}" } - false - end - end - - # Check for configuration files on a remote server. If found, copy to conf dir under each ver* dir - # @return [Void] - def override_default_config_remote - return unless @application.environment['APPD_CONF_HTTP_URL'] - - JavaBuildpack::Util::Cache::InternetAvailability.instance.available( - true, 'The AppDynamics remote configuration download location is always accessible' - ) do - agent_root = @application.environment['APPD_CONF_HTTP_URL'].chomp('/') + '/java/' - @logger.info { "Downloading override configuration files from #{agent_root}" } - CONFIG_FILES.each do |conf_file| - uri = URI(agent_root + conf_file) - - # `download()` uses retries with exponential backoff which is expensive - # for situations like 404 File not Found. Also, `download()` doesn't expose - # an api to disable retries, which makes this check necessary to prevent - # long install times. - next unless check_if_resource_exists(uri, conf_file) - - download(false, uri.to_s) do |file| - Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| - FileUtils.cp_r file, target_directory + '/conf/' + conf_file - end - end - end - end - end - # Check for configuration files locally. If found, copy to conf dir under each ver* dir # @return [Void] def override_default_config_local @@ -226,9 +171,13 @@ def override_default_config_local next unless File.file?(conf_file_path) - Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| - FileUtils.cp_r conf_file_path, target_directory + '/conf/' + conf_file - end + save_cfg_file(conf_file_path, conf_file) + end + end + + def save_cfg_file(file, conf_file) + Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| + FileUtils.cp_r file, target_directory + '/conf/' + conf_file end end end diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 748320b50c..8b3f15aba9 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -18,6 +18,7 @@ require 'fileutils' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' +require 'java_buildpack/util/external_config' require 'java_buildpack/util/qualify_path' module JavaBuildpack @@ -26,6 +27,18 @@ module Framework # Encapsulates the functionality for enabling zero-touch Safenet Luna HSM Java Security Provider support. class LunaSecurityProvider < JavaBuildpack::Component::VersionedDependencyComponent include JavaBuildpack::Util + include JavaBuildpack::Util::ExternalConfig + + # Full list of configuration files that can be downloaded remotely + CONFIG_FILES = %w[Chrystoki.conf server-certificates.pem].freeze + + # Prefix to be used with external configuration environment variable + CONFIG_PREFIX = 'LUNA' + + def initialize(context) + super(context) + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger LunaSecurityProvider + end # (see JavaBuildpack::Component::BaseComponent#compile) def compile @@ -36,10 +49,11 @@ def compile @droplet.security_providers << 'com.safenetinc.luna.provider.LunaProvider' @droplet.root_libraries << luna_provider_jar if @droplet.java_home.java_9_or_later? - credentials = @application.services.find_service(FILTER, 'client', 'servers', 'groups')['credentials'] - write_client credentials['client'] - write_servers credentials['servers'] - write_configuration credentials['servers'], credentials['groups'] + write_credentials + + override_default_config_remote do |file, conf_file| + FileUtils.cp_r file, @droplet.sandbox + conf_file + end end # (see JavaBuildpack::Component::BaseComponent#release) @@ -57,11 +71,27 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, 'client', 'servers', 'groups' + @application.services.one_service?(FILTER, 'client', 'servers', 'groups') || + @application.services.one_service?(FILTER, 'client', 'servers') || + @application.services.one_service?(FILTER, 'client') end private + def write_credentials + service = @application.services.find_service(FILTER, 'client', 'servers', 'groups') || + @application.services.find_service(FILTER, 'client', 'servers') || + @application.services.find_service(FILTER, 'client') + credentials = service['credentials'] + + write_client credentials['client'] if credentials.key? 'client' + write_servers credentials['servers'] if credentials.key? 'servers' + + return unless credentials.key?('servers') && credentials.key?('groups') + + write_configuration credentials['servers'], credentials['groups'] + end + FILTER = /luna/.freeze private_constant :FILTER @@ -254,6 +284,11 @@ def write_servers(servers) end end + # Overrides method from ExternalConfig module & provides root URL for where external configuration will be located + def external_config_root + @application.environment["#{CONFIG_PREFIX}_CONF_HTTP_URL"].chomp('/') + '/' + end + end end end diff --git a/lib/java_buildpack/util/external_config.rb b/lib/java_buildpack/util/external_config.rb new file mode 100644 index 0000000000..4cf2e5fba1 --- /dev/null +++ b/lib/java_buildpack/util/external_config.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/util' +require 'pathname' + +module JavaBuildpack + module Util + + # A module encapsulating all of the utility components for external configuration + module ExternalConfig + + # Root URL for where external configuration will be located + def external_config_root + @application.environment["#{self.class::CONFIG_PREFIX}_CONF_HTTP_URL"].chomp('/') + '/java/' + end + + # Check for configuration files on a remote server. If found, copy to conf dir under each ver* dir + # @return [Void] + def override_default_config_remote + return unless @application.environment["#{self.class::CONFIG_PREFIX}_CONF_HTTP_URL"] + + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, "The #{self.class.name} remote configuration download location is always accessible" + ) do + @logger.info { "Downloading override configuration files from #{external_config_root}" } + self.class::CONFIG_FILES.each do |conf_file| + uri = URI(external_config_root + conf_file) + + # `download()` uses retries with exponential backoff which is expensive + # for situations like 404 File not Found. Also, `download()` doesn't expose + # an api to disable retries, which makes this check necessary to prevent + # long install times. + next unless check_if_resource_exists(uri, conf_file) + + download('N/A', uri.to_s) do |file| + yield file, conf_file + end + end + end + end + + # Check if configuration file exists on the server before download + # @param [ResourceURI] resource_uri URI of the remote configuration server + # @param [ConfigFileName] conf_file Name of the configuration file + # @return [Boolean] returns true if files exists on path specified by resource_uri, false otherwise + def check_if_resource_exists(resource_uri, conf_file) + # check if resource exists on remote server + begin + opts = { use_ssl: true } if resource_uri.scheme == 'https' + response = Net::HTTP.start(resource_uri.host, resource_uri.port, opts) do |http| + req = Net::HTTP::Head.new(resource_uri) + if resource_uri.user != '' || resource_uri.password != '' + req.basic_auth(resource_uri.user, resource_uri.password) + end + http.request(req) + end + rescue StandardError => e + @logger.error { "Request failure: #{e.message}" } + return false + end + + case response + when Net::HTTPSuccess + true + when Net::HTTPRedirection + location = response['location'] + @logger.info { "redirected to #{location}" } + check_if_resource_exists(location, conf_file) + else + @logger.info { "Could not retrieve #{resource_uri}. Code: #{response.code} Message: #{response.message}" } + false + end + end + end + + end +end diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index ce37768f11..d6458de672 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -27,7 +27,90 @@ end context do + let(:vcap_services) do + { 'test-service-n/a' => [ + { + 'name' => 'luna-service', 'label' => 'luna-service-n/a', + 'tags' => ['luna-service-tag'], 'plan' => 'luna-plan', + 'credentials' => { + 'client' => { + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", + 'private-key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----" + }, + 'servers' => [ + { + 'name' => 'test-server-1', + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-1-cert\n-----END CERTIFICATE-----" + }, { + 'name' => 'test-server-2', + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-2-cert\n-----END CERTIFICATE-----" + } + ], + 'groups' => [{ + 'label' => 'test-group-1', + 'members' => %w[test-group-1-member-1 test-group-1-member-2] + }, { + 'label' => 'test-group-2', + 'members' => %w[test-group-2-member-1 test-group-2-member-2] + }] + } + } + ] } + end + + it 'detects with luna-n/a service with client, servers and groups' do + expect(component.detect).to eq("luna-security-provider=#{version}") + end + end + + context do + let(:vcap_services) do + { 'test-service-n/a' => [ + { 'name' => 'luna-service', 'label' => 'luna-service-n/a', + 'tags' => ['luna-service-tag'], 'plan' => 'luna-plan', + 'credentials' => { + 'client' => { + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", + 'private-key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----" + }, + 'servers' => [ + { + 'name' => 'test-server-1', + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-1-cert\n-----END CERTIFICATE-----" + }, { + 'name' => 'test-server-2', + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-2-cert\n-----END CERTIFICATE-----" + } + ] + } } + ] } + end + it 'detects with luna-n/a service with client and servers' do + expect(component.detect).to eq("luna-security-provider=#{version}") + end + end + + context do + let(:vcap_services) do + { 'test-service-n/a' => [ + { 'name' => 'luna-service', 'label' => 'luna-service-n/a', + 'tags' => ['luna-service-tag'], 'plan' => 'luna-plan', + 'credentials' => { + 'client' => { + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", + 'private-key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----" + } + } } + ] } + end + + it 'detects with luna-n/a service with just client' do + expect(component.detect).to eq("luna-security-provider=#{version}") + end + end + + context do before do allow(services).to receive(:one_service?).with(/luna/, 'client', 'servers', 'groups').and_return(true) @@ -158,6 +241,68 @@ end + context do + + let(:environment) { { 'LUNA_CONF_HTTP_URL' => 'http://foo.com' } } + let(:conf_files) { described_class.instance_variable_get(:@conf_files) } + + it 'sets LUNA_CONF_HTTP_URL env var to download config files from', + cache_fixture: 'stub-luna-security-provider.tar' do + + config_files = %w[Chrystoki.conf server-certificates.pem] + + config_files.each do |file| + uri = "http://foo.com/#{file}" + allow(application_cache).to receive(:get).with(uri) + stub_request(:head, uri) + .with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby' }) + .to_return(status: 200, body: '', headers: {}) + end + component.compile + end + + end + + context do + let(:environment) { { 'LUNA_CONF_HTTP_URL' => 'https://foo.com/' } } + + it 'sets LUNA_CONF_HTTP_URL env var to download config files over HTTPS', + cache_fixture: 'stub-luna-security-provider.tar' do + + config_files = %w[Chrystoki.conf server-certificates.pem] + + config_files.each do |file| + uri = "https://foo.com/#{file}" + allow(application_cache).to receive(:get).with(uri) + allow(Net::HTTP).to receive(:start).with('foo.com', 443, use_ssl: true).and_call_original + stub_request(:head, uri) + .with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby' }) + .to_return(status: 200, body: '', headers: {}) + end + component.compile + end + end + + context do + let(:environment) { { 'LUNA_CONF_HTTP_URL' => 'https://user:pass@foo.com' } } + + it 'sets LUNA_CONF_HTTP_URL env var to download config files over HTTPS with Basic Auth', + cache_fixture: 'stub-luna-security-provider.tar' do + + config_files = %w[Chrystoki.conf server-certificates.pem] + + config_files.each do |file| + allow(application_cache).to receive(:get).with("https://user:pass@foo.com/#{file}") + allow(Net::HTTP).to receive(:start).with('foo.com', 443, use_ssl: true).and_call_original + stub_request(:head, "https://foo.com/#{file}") + .with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby', + 'Authorization' => 'Basic dXNlcjpwYXNz' }) + .to_return(status: 200, body: '', headers: {}) + end + component.compile + end + end + context do let(:configuration) do { From 26618ea12074e4379b9f3e79043e81ead33bd240 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 26 May 2021 10:35:39 -0400 Subject: [PATCH 642/812] Adds external configuration support for Luna Security Module (#879) - Extracts external configuration code into a utility - Modifies AppDynamics to use the utility code - Modifies Luna Security Provider to use the utility code - Updates documentation for AppDynamics and Luna to explaini how external configuration works --- Gemfile.lock | 4 +- docs/framework-app_dynamics_agent.md | 46 +++++- docs/framework-luna_security_provider.md | 22 ++- .../framework/app_dynamics_agent.rb | 89 +++-------- .../framework/luna_security_provider.rb | 45 +++++- lib/java_buildpack/util/external_config.rb | 92 +++++++++++ .../framework/luna_security_provider_spec.rb | 145 ++++++++++++++++++ 7 files changed, 364 insertions(+), 79 deletions(-) create mode 100644 lib/java_buildpack/util/external_config.rb diff --git a/Gemfile.lock b/Gemfile.lock index 5d0222e4c3..689eda08b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,8 +15,8 @@ GEM public_suffix (4.0.4) rainbow (3.0.0) rake (13.0.1) - rexml (3.2.5) redcarpet (3.5.1) + rexml (3.2.5) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) @@ -69,4 +69,4 @@ DEPENDENCIES yard BUNDLED WITH - 2.1.4 + 2.2.16 diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index 7a74a0d3c4..c0f76c135c 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -44,7 +44,51 @@ The framework can be configured by modifying the [`config/app_dynamics_agent.yml | `version` | The version of AppDynamics to use. Candidate versions can be found in [this listing][]. ### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/app_dynamics_agent` directory in the buildpack fork. For example, to override the default `app-agent-config.xml` add your custom file to `resources/app_dynamics_agent//conf/app-agent-config.xml`. +The framework can also be configured by overlaying a set of resources on the default distribution. To do this follow one of the options below. + +Configuration files are created in this order: + +1. Default AppDynamics configuration +2. Buildpack default configuration is taken from `resources/app_dynamics_agent/default` +3. External Configuration if configured +4. Local Configuration if configured +5. Buildpack Fork if it exists + +#### Buildpack Fork +Add files to the `resources/app_dynamics_agent` directory in the buildpack fork. For example, to override the default `app-agent-config.xml` add your custom file to `resources/app_dynamics_agent//conf/app-agent-config.xml`. + +#### External Configuration +Set `APPD_CONF_HTTP_URL` to an HTTP or HTTPS URL which points to the directory where your configuration files exist. You may also include a user and password in the URL, like `https://user:pass@example.com`. + +The Java buildpack will take the URL to the directory provided and attempt to download the following files from that directory: + +- `logging/log4j2.xml` +- `logging/log4j.xml` +- `app-agent-config.xml` +- `controller-info.xml` +- `service-endpoint.xml` +- `transactions.xml` +- `custom-interceptors.xml` +- `custom-activity-correlation.xml` + +Any file successfully downloaded will be copied to the configuration directory. The buildpack does not fail if files are missing. + +#### Local Configuration +Set `APPD_CONF_DIR` to a relative path which points to the directory in your application files where your custom configuration exists. + +The Java buildpack will take the `app_root` + `APPD_CONF_DIR` directory and attempt to copy the followinig files from that directory: + +- `logging/log4j2.xml` +- `logging/log4j.xml` +- `app-agent-config.xml` +- `controller-info.xml` +- `service-endpoint.xml` +- `transactions.xml` +- `custom-interceptors.xml` +- `custom-activity-correlation.xml` + +Any files that exist will be copied to the configuration directory. The buildpack does not fail if files are missing. + [`config/app_dynamics_agent.yml`]: ../config/app_dynamics_agent.yml [AppDynamics Java Agent Configuration Properties]: https://docs.appdynamics.com/display/PRO42/Java+Agent+Configuration+Properties diff --git a/docs/framework-luna_security_provider.md b/docs/framework-luna_security_provider.md index a749dedfb6..7fd8ad0cda 100644 --- a/docs/framework-luna_security_provider.md +++ b/docs/framework-luna_security_provider.md @@ -98,7 +98,27 @@ The framework can be configured by modifying the [`config/luna_security_provider | `version` | Version of the Luna Security Provider to use. ### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/luna_security_provider` directory in the buildpack fork. +The framework can also be configured by overlaying a set of resources on the default distribution. To do this follow one of the options below. + +Configuration files are created in this order: + +1. Default configuration +2. Buildpack fork +3. Buildpack generated configuration if the bound service has both a `servers` and `groups` key +4. External configuration if configured + +#### Buildpack Fork +Add files to the `resources/luna_security_provider` directory in the buildpack fork. For example, to override the default `Chrystoki.conf` add your custom file to `resources/luna_security_provider/Chrystoki.conf`. + +#### External Configuration +Set `LUNA_CONF_HTTP_URL` to an HTTP or HTTPS URL which points to the directory where your configuration files exist. You may also include a user and password in the URL, like `https://user:pass@example.com`. + +The Java buildpack will take the URL to the directory provided and attempt to download the following files from that directory: + +- `Chrystoki.conf` +- `server-certificates.pem` + +Any file successfully downloaded will be copied to the configuration directory. The buildpack does not fail if files are missing. [`config/luna_security_provider.yml`]: ../config/luna_security_provider.yml [Luna Security Service]: http://www.safenet-inc.com/data-encryption/hardware-security-modules-hsms/ diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 9e21b7510b..545ff70daa 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -19,12 +19,22 @@ require 'shellwords' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' +require 'java_buildpack/util/external_config' module JavaBuildpack module Framework # Encapsulates the functionality for enabling zero-touch AppDynamics support. class AppDynamicsAgent < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util::ExternalConfig + + # Full list of configuration files that can be downloaded remotely + CONFIG_FILES = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml + service-endpoint.xml transactions.xml custom-interceptors.xml + custom-activity-correlation.xml].freeze + + # Prefix to be used with external configuration environment variable + CONFIG_PREFIX = 'APPD' def initialize(context) super(context) @@ -40,7 +50,7 @@ def compile default_conf_dir = resources_dir + @droplet.component_id + 'defaults' copy_appd_default_configuration(default_conf_dir) - override_default_config_remote + override_default_config_remote(&method(:save_cfg_file)) override_default_config_local @droplet.copy_resources end @@ -71,13 +81,9 @@ def supports? private - CONFIG_FILES = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml - service-endpoint.xml transactions.xml custom-interceptors.xml - custom-activity-correlation.xml].freeze - FILTER = /app[-]?dynamics/.freeze - private_constant :CONFIG_FILES, :FILTER + private_constant :FILTER def application_name(java_opts, credentials) name = Shellwords.escape(@application.details['application_name']) @@ -150,67 +156,6 @@ def copy_appd_default_configuration(default_conf_dir) end end - # Check if configuration file exists on the server before download - # @param [ResourceURI] uri URI of the remote configuration server - # @param [ConfigFileName] conf_file Name of the configuration file - # @return [Boolean] returns true if files exists on path specified by APPD_CONF_HTTP_URL, false otherwise - def check_if_resource_exists(resource_uri, conf_file) - # check if resource exists on remote server - begin - opts = { use_ssl: true } if resource_uri.scheme == 'https' - response = Net::HTTP.start(resource_uri.host, resource_uri.port, opts) do |http| - req = Net::HTTP::Head.new(resource_uri) - if resource_uri.user != '' || resource_uri.password != '' - req.basic_auth(resource_uri.user, resource_uri.password) - end - http.request(req) - end - rescue StandardError => e - @logger.error { "Request failure: #{e.message}" } - return false - end - - case response - when Net::HTTPSuccess - true - when Net::HTTPRedirection - location = response['location'] - @logger.info { "redirected to #{location}" } - check_if_resource_exists(location, conf_file) - else - @logger.info { "Could not retrieve #{resource_uri}. Code: #{response.code} Message: #{response.message}" } - false - end - end - - # Check for configuration files on a remote server. If found, copy to conf dir under each ver* dir - # @return [Void] - def override_default_config_remote - return unless @application.environment['APPD_CONF_HTTP_URL'] - - JavaBuildpack::Util::Cache::InternetAvailability.instance.available( - true, 'The AppDynamics remote configuration download location is always accessible' - ) do - agent_root = @application.environment['APPD_CONF_HTTP_URL'].chomp('/') + '/java/' - @logger.info { "Downloading override configuration files from #{agent_root}" } - CONFIG_FILES.each do |conf_file| - uri = URI(agent_root + conf_file) - - # `download()` uses retries with exponential backoff which is expensive - # for situations like 404 File not Found. Also, `download()` doesn't expose - # an api to disable retries, which makes this check necessary to prevent - # long install times. - next unless check_if_resource_exists(uri, conf_file) - - download(false, uri.to_s) do |file| - Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| - FileUtils.cp_r file, target_directory + '/conf/' + conf_file - end - end - end - end - end - # Check for configuration files locally. If found, copy to conf dir under each ver* dir # @return [Void] def override_default_config_local @@ -226,9 +171,13 @@ def override_default_config_local next unless File.file?(conf_file_path) - Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| - FileUtils.cp_r conf_file_path, target_directory + '/conf/' + conf_file - end + save_cfg_file(conf_file_path, conf_file) + end + end + + def save_cfg_file(file, conf_file) + Dir.glob(@droplet.sandbox + 'ver*') do |target_directory| + FileUtils.cp_r file, target_directory + '/conf/' + conf_file end end end diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 748320b50c..8b3f15aba9 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -18,6 +18,7 @@ require 'fileutils' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' +require 'java_buildpack/util/external_config' require 'java_buildpack/util/qualify_path' module JavaBuildpack @@ -26,6 +27,18 @@ module Framework # Encapsulates the functionality for enabling zero-touch Safenet Luna HSM Java Security Provider support. class LunaSecurityProvider < JavaBuildpack::Component::VersionedDependencyComponent include JavaBuildpack::Util + include JavaBuildpack::Util::ExternalConfig + + # Full list of configuration files that can be downloaded remotely + CONFIG_FILES = %w[Chrystoki.conf server-certificates.pem].freeze + + # Prefix to be used with external configuration environment variable + CONFIG_PREFIX = 'LUNA' + + def initialize(context) + super(context) + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger LunaSecurityProvider + end # (see JavaBuildpack::Component::BaseComponent#compile) def compile @@ -36,10 +49,11 @@ def compile @droplet.security_providers << 'com.safenetinc.luna.provider.LunaProvider' @droplet.root_libraries << luna_provider_jar if @droplet.java_home.java_9_or_later? - credentials = @application.services.find_service(FILTER, 'client', 'servers', 'groups')['credentials'] - write_client credentials['client'] - write_servers credentials['servers'] - write_configuration credentials['servers'], credentials['groups'] + write_credentials + + override_default_config_remote do |file, conf_file| + FileUtils.cp_r file, @droplet.sandbox + conf_file + end end # (see JavaBuildpack::Component::BaseComponent#release) @@ -57,11 +71,27 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, 'client', 'servers', 'groups' + @application.services.one_service?(FILTER, 'client', 'servers', 'groups') || + @application.services.one_service?(FILTER, 'client', 'servers') || + @application.services.one_service?(FILTER, 'client') end private + def write_credentials + service = @application.services.find_service(FILTER, 'client', 'servers', 'groups') || + @application.services.find_service(FILTER, 'client', 'servers') || + @application.services.find_service(FILTER, 'client') + credentials = service['credentials'] + + write_client credentials['client'] if credentials.key? 'client' + write_servers credentials['servers'] if credentials.key? 'servers' + + return unless credentials.key?('servers') && credentials.key?('groups') + + write_configuration credentials['servers'], credentials['groups'] + end + FILTER = /luna/.freeze private_constant :FILTER @@ -254,6 +284,11 @@ def write_servers(servers) end end + # Overrides method from ExternalConfig module & provides root URL for where external configuration will be located + def external_config_root + @application.environment["#{CONFIG_PREFIX}_CONF_HTTP_URL"].chomp('/') + '/' + end + end end end diff --git a/lib/java_buildpack/util/external_config.rb b/lib/java_buildpack/util/external_config.rb new file mode 100644 index 0000000000..4cf2e5fba1 --- /dev/null +++ b/lib/java_buildpack/util/external_config.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/util' +require 'pathname' + +module JavaBuildpack + module Util + + # A module encapsulating all of the utility components for external configuration + module ExternalConfig + + # Root URL for where external configuration will be located + def external_config_root + @application.environment["#{self.class::CONFIG_PREFIX}_CONF_HTTP_URL"].chomp('/') + '/java/' + end + + # Check for configuration files on a remote server. If found, copy to conf dir under each ver* dir + # @return [Void] + def override_default_config_remote + return unless @application.environment["#{self.class::CONFIG_PREFIX}_CONF_HTTP_URL"] + + JavaBuildpack::Util::Cache::InternetAvailability.instance.available( + true, "The #{self.class.name} remote configuration download location is always accessible" + ) do + @logger.info { "Downloading override configuration files from #{external_config_root}" } + self.class::CONFIG_FILES.each do |conf_file| + uri = URI(external_config_root + conf_file) + + # `download()` uses retries with exponential backoff which is expensive + # for situations like 404 File not Found. Also, `download()` doesn't expose + # an api to disable retries, which makes this check necessary to prevent + # long install times. + next unless check_if_resource_exists(uri, conf_file) + + download('N/A', uri.to_s) do |file| + yield file, conf_file + end + end + end + end + + # Check if configuration file exists on the server before download + # @param [ResourceURI] resource_uri URI of the remote configuration server + # @param [ConfigFileName] conf_file Name of the configuration file + # @return [Boolean] returns true if files exists on path specified by resource_uri, false otherwise + def check_if_resource_exists(resource_uri, conf_file) + # check if resource exists on remote server + begin + opts = { use_ssl: true } if resource_uri.scheme == 'https' + response = Net::HTTP.start(resource_uri.host, resource_uri.port, opts) do |http| + req = Net::HTTP::Head.new(resource_uri) + if resource_uri.user != '' || resource_uri.password != '' + req.basic_auth(resource_uri.user, resource_uri.password) + end + http.request(req) + end + rescue StandardError => e + @logger.error { "Request failure: #{e.message}" } + return false + end + + case response + when Net::HTTPSuccess + true + when Net::HTTPRedirection + location = response['location'] + @logger.info { "redirected to #{location}" } + check_if_resource_exists(location, conf_file) + else + @logger.info { "Could not retrieve #{resource_uri}. Code: #{response.code} Message: #{response.message}" } + false + end + end + end + + end +end diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index ce37768f11..d6458de672 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -27,7 +27,90 @@ end context do + let(:vcap_services) do + { 'test-service-n/a' => [ + { + 'name' => 'luna-service', 'label' => 'luna-service-n/a', + 'tags' => ['luna-service-tag'], 'plan' => 'luna-plan', + 'credentials' => { + 'client' => { + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", + 'private-key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----" + }, + 'servers' => [ + { + 'name' => 'test-server-1', + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-1-cert\n-----END CERTIFICATE-----" + }, { + 'name' => 'test-server-2', + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-2-cert\n-----END CERTIFICATE-----" + } + ], + 'groups' => [{ + 'label' => 'test-group-1', + 'members' => %w[test-group-1-member-1 test-group-1-member-2] + }, { + 'label' => 'test-group-2', + 'members' => %w[test-group-2-member-1 test-group-2-member-2] + }] + } + } + ] } + end + + it 'detects with luna-n/a service with client, servers and groups' do + expect(component.detect).to eq("luna-security-provider=#{version}") + end + end + + context do + let(:vcap_services) do + { 'test-service-n/a' => [ + { 'name' => 'luna-service', 'label' => 'luna-service-n/a', + 'tags' => ['luna-service-tag'], 'plan' => 'luna-plan', + 'credentials' => { + 'client' => { + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", + 'private-key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----" + }, + 'servers' => [ + { + 'name' => 'test-server-1', + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-1-cert\n-----END CERTIFICATE-----" + }, { + 'name' => 'test-server-2', + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-server-2-cert\n-----END CERTIFICATE-----" + } + ] + } } + ] } + end + it 'detects with luna-n/a service with client and servers' do + expect(component.detect).to eq("luna-security-provider=#{version}") + end + end + + context do + let(:vcap_services) do + { 'test-service-n/a' => [ + { 'name' => 'luna-service', 'label' => 'luna-service-n/a', + 'tags' => ['luna-service-tag'], 'plan' => 'luna-plan', + 'credentials' => { + 'client' => { + 'certificate' => "-----BEGIN CERTIFICATE-----\ntest-client-cert\n-----END CERTIFICATE-----", + 'private-key' => "-----BEGIN RSA PRIVATE KEY-----\ntest-client-private-key\n-----END RSA PRIVATE KEY-----" + } + } } + ] } + end + + it 'detects with luna-n/a service with just client' do + expect(component.detect).to eq("luna-security-provider=#{version}") + end + end + + context do before do allow(services).to receive(:one_service?).with(/luna/, 'client', 'servers', 'groups').and_return(true) @@ -158,6 +241,68 @@ end + context do + + let(:environment) { { 'LUNA_CONF_HTTP_URL' => 'http://foo.com' } } + let(:conf_files) { described_class.instance_variable_get(:@conf_files) } + + it 'sets LUNA_CONF_HTTP_URL env var to download config files from', + cache_fixture: 'stub-luna-security-provider.tar' do + + config_files = %w[Chrystoki.conf server-certificates.pem] + + config_files.each do |file| + uri = "http://foo.com/#{file}" + allow(application_cache).to receive(:get).with(uri) + stub_request(:head, uri) + .with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby' }) + .to_return(status: 200, body: '', headers: {}) + end + component.compile + end + + end + + context do + let(:environment) { { 'LUNA_CONF_HTTP_URL' => 'https://foo.com/' } } + + it 'sets LUNA_CONF_HTTP_URL env var to download config files over HTTPS', + cache_fixture: 'stub-luna-security-provider.tar' do + + config_files = %w[Chrystoki.conf server-certificates.pem] + + config_files.each do |file| + uri = "https://foo.com/#{file}" + allow(application_cache).to receive(:get).with(uri) + allow(Net::HTTP).to receive(:start).with('foo.com', 443, use_ssl: true).and_call_original + stub_request(:head, uri) + .with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby' }) + .to_return(status: 200, body: '', headers: {}) + end + component.compile + end + end + + context do + let(:environment) { { 'LUNA_CONF_HTTP_URL' => 'https://user:pass@foo.com' } } + + it 'sets LUNA_CONF_HTTP_URL env var to download config files over HTTPS with Basic Auth', + cache_fixture: 'stub-luna-security-provider.tar' do + + config_files = %w[Chrystoki.conf server-certificates.pem] + + config_files.each do |file| + allow(application_cache).to receive(:get).with("https://user:pass@foo.com/#{file}") + allow(Net::HTTP).to receive(:start).with('foo.com', 443, use_ssl: true).and_call_original + stub_request(:head, "https://foo.com/#{file}") + .with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby', + 'Authorization' => 'Basic dXNlcjpwYXNz' }) + .to_return(status: 200, body: '', headers: {}) + end + component.compile + end + end + context do let(:configuration) do { From e6bb731a17a705517def7dc2bc8c0112ef3c31ea Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 26 May 2021 10:56:21 -0400 Subject: [PATCH 643/812] Enable pulling the application version for DataDog from the DD_VERSION environment variable. --- lib/java_buildpack/framework/datadog_javaagent.rb | 5 ++--- .../framework/datadog_javaagent_spec.rb | 14 +++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/framework/datadog_javaagent.rb b/lib/java_buildpack/framework/datadog_javaagent.rb index a5a88d3916..2fe4cd5faa 100644 --- a/lib/java_buildpack/framework/datadog_javaagent.rb +++ b/lib/java_buildpack/framework/datadog_javaagent.rb @@ -50,9 +50,8 @@ def release java_opts.add_system_property('dd.service', "\\\"#{app_name}\\\"") end - return if @application.environment.key?('DD_VERSION') || !@application.details['application_version'] - - version = @configuration['default_application_version'] || @application.details['application_version'] + version = @application.environment['DD_VERSION'] || @configuration['default_application_version'] || + @application.details['application_version'] java_opts.add_system_property('dd.version', version) end diff --git a/spec/java_buildpack/framework/datadog_javaagent_spec.rb b/spec/java_buildpack/framework/datadog_javaagent_spec.rb index 6e39d57bc0..185ac6ae7a 100644 --- a/spec/java_buildpack/framework/datadog_javaagent_spec.rb +++ b/spec/java_buildpack/framework/datadog_javaagent_spec.rb @@ -110,13 +110,21 @@ context 'when dd_version environment variable is provided' do let(:environment) do - super().update({ 'DD_VERSION' => 'test-application-version' }) + super().update({ 'DD_VERSION' => 'env-variable-version' }) end - it 'release updates JAVA_OPTS' do + before do + FileUtils.mkdir_p File.join(context[:droplet].root, 'datadog') + end + + after do + FileUtils.rmdir File.join(context[:droplet].root, 'datadog') + end + + it 'release updates JAVA_OPTS with env variable version' do component.release - expect(java_opts).not_to include('-Ddd.version=test-application-version') + expect(java_opts).to include('-Ddd.version=env-variable-version') end end end From 51bb898bb095b7508576e9a9ea39cacc52e1e9a7 Mon Sep 17 00:00:00 2001 From: Michael Messmore Date: Fri, 11 Jun 2021 09:41:05 -0500 Subject: [PATCH 644/812] Restore unique_host_name logic (#884) PR #870 reversed the logic overriding the default_unique_host_name with the application_name. This results in problems with AppDynamics where applications running on multiple foundations are unable to add metrics when using the same application name in Cloud Foundry. Really, application_name should never be used. unique_host_name is by definition a unique identifier vs an application_name, which is not guaranteed to be unique. But this restores the previous logic, which was functional and may have handled cases I am not aware of. --- lib/java_buildpack/framework/app_dynamics_agent.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index 545ff70daa..dada5ce87b 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -138,8 +138,8 @@ def tier_name(java_opts, credentials) end def unique_host_name(java_opts) - name = @configuration['default_unique_host_name'] - name = Shellwords.escape(@application.details['application_name']) if @application.details['application_name'] + name = Shellwords.escape(@application.details['application_name']) + name = @configuration['default_unique_host_name'] if @configuration['default_unique_host_name'] java_opts.add_system_property('appdynamics.agent.uniqueHostId', name.to_s) end From be2fb8992d00738e7728d40ae89f5d47660da565 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 1 Jul 2021 14:43:31 -0400 Subject: [PATCH 645/812] Sanitize URLs before logging them (#889) --- lib/java_buildpack/util/external_config.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/util/external_config.rb b/lib/java_buildpack/util/external_config.rb index 4cf2e5fba1..a37bedd47d 100644 --- a/lib/java_buildpack/util/external_config.rb +++ b/lib/java_buildpack/util/external_config.rb @@ -16,6 +16,7 @@ # limitations under the License. require 'java_buildpack/util' +require 'java_buildpack/util/sanitizer' require 'pathname' module JavaBuildpack @@ -37,7 +38,7 @@ def override_default_config_remote JavaBuildpack::Util::Cache::InternetAvailability.instance.available( true, "The #{self.class.name} remote configuration download location is always accessible" ) do - @logger.info { "Downloading override configuration files from #{external_config_root}" } + @logger.info { "Downloading override configuration files from #{external_config_root.sanitize_uri}" } self.class::CONFIG_FILES.each do |conf_file| uri = URI(external_config_root + conf_file) @@ -79,10 +80,11 @@ def check_if_resource_exists(resource_uri, conf_file) true when Net::HTTPRedirection location = response['location'] - @logger.info { "redirected to #{location}" } + @logger.info { "redirected to #{location.sanitize_uri}" } check_if_resource_exists(location, conf_file) else - @logger.info { "Could not retrieve #{resource_uri}. Code: #{response.code} Message: #{response.message}" } + clean_url = resource_uri.to_s.sanitize_uri + @logger.info { "Could not fetch #{clean_url}. Code: #{response.code} - #{response.message}" } false end end From 37acdfe3548634a04856a595d09ed97333c61e2e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Jul 2021 16:17:31 -0400 Subject: [PATCH 646/812] Bump addressable from 2.7.0 to 2.8.0 (#891) Bumps [addressable](https://github.com/sporkmonger/addressable) from 2.7.0 to 2.8.0. - [Release notes](https://github.com/sporkmonger/addressable/releases) - [Changelog](https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md) - [Commits](https://github.com/sporkmonger/addressable/compare/addressable-2.7.0...addressable-2.8.0) --- updated-dependencies: - dependency-name: addressable dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 689eda08b1..e980a3aa17 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.7.0) + addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) ast (2.4.0) crack (0.4.3) @@ -12,7 +12,7 @@ GEM parallel (1.19.1) parser (2.7.1.1) ast (~> 2.4.0) - public_suffix (4.0.4) + public_suffix (4.0.6) rainbow (3.0.0) rake (13.0.1) redcarpet (3.5.1) From 5483a8785b15f1d519a7e02e87cec760c7bed64b Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Wed, 14 Jul 2021 22:43:04 +0200 Subject: [PATCH 647/812] Added `networkzone` parameter to service bindinig for agent download and remove AppMon components (#893) * added `networkzone` parameter the service binding configuration for for Dynatrace. This is passed through to the URL from which the Dynatrace OneAgent is downloaded. * remove Dynatrace AppMon support as this product is deprecated and and OneAgent should be used going forward. --- README.md | 1 - config/dynatrace_appmon_agent.yml | 20 ---- docs/framework-dynatrace_appmon_agent.md | 94 --------------- .../framework/dynatrace_appmon_agent.rb | 108 ------------------ .../framework/dynatrace_one_agent.rb | 8 +- rakelib/versions_task.rb | 1 - .../framework/dynatrace_appmon_agent_spec.rb | 89 --------------- 7 files changed, 7 insertions(+), 314 deletions(-) delete mode 100644 config/dynatrace_appmon_agent.yml delete mode 100644 docs/framework-dynatrace_appmon_agent.md delete mode 100644 lib/java_buildpack/framework/dynatrace_appmon_agent.rb delete mode 100644 spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb diff --git a/README.md b/README.md index c0ed3b1fb2..1c66c9838b 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,6 @@ The buildpack supports extension through the use of Git repository forking. The * [Container Security Provider](docs/framework-container_security_provider.md) ([Configuration](docs/framework-container_security_provider.md#configuration)) * [Contrast Security Agent](docs/framework-contrast_security_agent.md) ([Configuration](docs/framework-contrast_security_agent.md#configuration)) * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) - * [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration)) * [Elastic APM Agent](docs/framework-elastic_apm_agent.md) ([Configuration](docs/framework-elastic_apm_agent.md#configuration)) * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) * [Google Stackdriver Debugger](docs/framework-google_stackdriver_debugger.md) ([Configuration](docs/framework-google_stackdriver_debugger.md#configuration)) diff --git a/config/dynatrace_appmon_agent.yml b/config/dynatrace_appmon_agent.yml deleted file mode 100644 index 79126c66a3..0000000000 --- a/config/dynatrace_appmon_agent.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Configuration for the Dynatrace framework ---- -version: 7.1.0_+ -repository_root: https://files.dynatrace.com/downloads/appmon/cloudfoundry/buildpack/java -default_agent_name: diff --git a/docs/framework-dynatrace_appmon_agent.md b/docs/framework-dynatrace_appmon_agent.md deleted file mode 100644 index a720a4a9df..0000000000 --- a/docs/framework-dynatrace_appmon_agent.md +++ /dev/null @@ -1,94 +0,0 @@ -# Dynatrace Appmon Agent Framework -The Dynatrace Appmon Agent Framework causes an application to be automatically configured to work with a bound [Dynatrace Service][] instance (Free trials available). - -The application's Cloud Foundry name is used as the `agent group` in Dynatrace Appmon, and must be pre-configured on the Dynatrace server. - -**NOTE** - -* The Dynatrace Appmon agent may slow down the start up time of large applications at first, but gets faster over time. Setting the application manifest to contain `maximum_health_check_timeout` of 180 or more and/or using `cf push -t 180` or more when pushing the application may help. -* Unsuccessful `cf push`s will cause dead entries to build up in the Dynatrace Appmon dashboard, as CF launches/disposes application containers. These can be hidden but will collect in the Dynatrace database. - - - - - - - - - -
Detection CriterionExistence of a single bound Dynatrace Appmon service. -
    -
  • Existence of a Dynatrace Appmon service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has dynatrace as a substring and contains server field in the credentials. Note: The credentials must NOT contain tenant and tenanttoken in order to make sure the detection mechanism does not interfere with Dynatrace SaaS/Managed integration.
  • -
-
Tagsdynatrace-appmon-agent=<version>
-Tags are printed to standard output by the buildpack detect script - -## User-Provided Service -Users must provide their own Dynatrace Appmon service. A user-provided Dynatrace Appmon service must have a name or tag with `dynatrace` in it so that the Dynatrace Appmon Agent Framework will automatically configure the application to work with the service. - -The credential payload of the service may contain the following entries: - -| Name | Description -| ---- | ----------- -| `server` | The Dynatrace collector hostname to connect to. Use `host:port` format for a specific port number. -| `profile` | (Optional) The Dynatrace server profile this is associated with. Uses `Monitoring` by default. - -### Example Dynatrace User-Provided Service Payload -``` -{ - "server":"my-dynatrace-server:my-port", - "profile":"my-dynatrace-profile" -} -``` - -### Creating Dynatrace User-Provided Service Payload -In order to create the Dynatrace configuration payload, you should collapse the JSON payload to a single line and set it like the following... The user-provided Dynatrace Appmon service must have a name of or tag with `dynatrace` in it. For example: my-dynatrace-service. - -``` -cf cups my-dynatrace-service -p '{"server":"my-dynatrace-server:my-port","profile":"my-dynatrace-profile"}' -cf bind-service my-app-name my-dynatrace-service -``` - -**NOTE** - -Be sure to open an Application Security Group to your Dynatrace collector prior to starting the application: -``` -$ cat security.json - [ - { - "protocol": "tcp", - "destination": "dynatrace_host", - "ports": "9998" - } - ] - -$ cf create-security-group dynatrace_group ./security.json -Creating security group dynatrace_group as admin -OK - -$ cf bind-running-security-group dynatrace_group -Binding security group dynatrace_group to defaults for running as admin -OK - -TIP: Changes will not apply to existing running applications until they are restarted. -``` - -## Configuration -For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. - -The framework can be configured by modifying the [`config/dynatrace_appmon_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. - -| Name | Description -| ---- | ----------- -| `repository_root` | The URL of the Dynatrace Appmon repository index ([details][repositories]). -| `version` | The version of Dynatrace Appmon to use. This buildpack framework has been tested on 6.1.0. -| `default_agent_name` | This is omitted by default but can be added to set the Dynatrace Appmon agent name. If it is not specified then `#{application_name}_#{profile_name}` is used, where `application_name` is defined by Cloud Foundry. - -### Additional Resources -The framework can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/dynatrace_appmon_agent` directory in the buildpack fork. - -[Configuration and Extension]: ../README.md#configuration-and-extension -[`config/dynatrace_appmon_agent.yml`]: ../config/dynatrace_appmon_agent.yml -[Dynatrace Service]: https://www.dynatrace.com/ -[repositories]: extending-repositories.md -[version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb b/lib/java_buildpack/framework/dynatrace_appmon_agent.rb deleted file mode 100644 index d19a71ddb6..0000000000 --- a/lib/java_buildpack/framework/dynatrace_appmon_agent.rb +++ /dev/null @@ -1,108 +0,0 @@ -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'fileutils' -require 'java_buildpack/component/versioned_dependency_component' -require 'java_buildpack/framework' -require 'java_buildpack/util/qualify_path' - -module JavaBuildpack - module Framework - - # Encapsulates the functionality for enabling zero-touch Dynatrace support. - class DynatraceAppmonAgent < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Util - - # (see JavaBuildpack::Component::BaseComponent#compile) - def compile - download(@version, @uri) { |file| expand file } - @droplet.copy_resources - end - - # (see JavaBuildpack::Component::BaseComponent#release) - def release - @droplet.java_opts.add_agentpath_with_props(agent_path, name: agent_name, server: server) - @droplet.java_opts.add_preformatted_options('-Xshare:off') - end - - protected - - # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) - def supports? - (@application.services.one_service? FILTER, 'server') && - !(@application.services.one_service? FILTER, 'tenant') && - !(@application.services.one_service? FILTER, 'tenanttoken') - end - - private - - FILTER = /dynatrace/.freeze - - private_constant :FILTER - - def agent_dir - @droplet.sandbox + 'agent' - end - - def agent_path - agent_dir + lib_name + 'libdtagent.so' - end - - def agent_name - @configuration['default_agent_name'] || "#{@application.details['application_name']}_#{profile_name}" - end - - def architecture - `uname -m`.strip - end - - def expand(file) - with_timing "Expanding Dynatrace Appmon to #{@droplet.sandbox.relative_path_from(@droplet.root)}" do - Dir.mktmpdir do |root| - root_path = Pathname.new(root) - shell "unzip -qq #{file.path} -d #{root_path} 2>&1" - unpack_agent root_path - end - end - end - - def lib_name - architecture == 'x86_64' || architecture == 'i686' ? 'lib64' : 'lib' - end - - def agent_unpack_path - architecture == 'x86_64' || architecture == 'i686' ? 'linux-x86-64/agent' : 'linux-x86-32/agent' - end - - def unpack_agent(root) - FileUtils.mkdir_p(agent_dir) - FileUtils.mv(root + 'agent' + agent_unpack_path + 'conf', agent_dir) - FileUtils.mv(root + 'agent' + agent_unpack_path + lib_name, agent_dir) - end - - def profile_name - @application.services.find_service(FILTER)['credentials']['profile'] || 'Monitoring' - end - - def server - @application.services.find_service(FILTER)['credentials']['server'] - end - - end - - end -end diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index adb83b3bea..e171e9bda5 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -112,7 +112,13 @@ def supports? def agent_download_url download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ - "&bitness=64&Api-Token=#{credentials[APITOKEN]}" + "&bitness=64" \ + "&Api-Token=#{credentials[APITOKEN]}" + # + # setting networkzone parameter if it's configured + if networkzone? + download_uri += "&networkzone=#{networkzone_value}" + ['latest', download_uri] end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index ebc7313d98..0ca08ce06f 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -61,7 +61,6 @@ def initialize 'container_security_provider' => 'Container Security Provider', 'contrast_security_agent' => 'Contrast Security Agent', 'datadog_javaagent' => 'Datadog APM Javaagent', - 'dynatrace_appmon_agent' => 'Dynatrace Appmon Agent', 'dynatrace_one_agent' => 'Dynatrace OneAgent', 'elastic_apm_agent' => 'Elastic APM Agent', 'geode_store' => 'Geode Tomcat Session Store', diff --git a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb deleted file mode 100644 index 08f0a0d9e0..0000000000 --- a/spec/java_buildpack/framework/dynatrace_appmon_agent_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'spec_helper' -require 'component_helper' -require 'java_buildpack/framework/dynatrace_appmon_agent' - -describe JavaBuildpack::Framework::DynatraceAppmonAgent do - include_context 'with component help' - - let(:configuration) do - { 'default_agent_name' => nil } - end - - it 'does not detect without dynatrace-n/a service' do - expect(component.detect).to be_nil - end - - context do - - before do - allow(services).to receive(:one_service?).with(/dynatrace/, 'server').and_return(true) - allow(services).to receive(:one_service?).with(/dynatrace/, 'tenant').and_return(false) - allow(services).to receive(:one_service?).with(/dynatrace/, 'tenanttoken').and_return(false) - allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name' }) - end - - it 'detects with dynatrace-n/a service' do - expect(component.detect).to eq("dynatrace-appmon-agent=#{version}") - end - - it 'expands DynaTrace agent zip', - cache_fixture: 'stub-dynatrace-appmon-agent.jar' do - - component.compile - expect(sandbox + 'agent/lib64/libdtagent.so').to exist - end - - it 'updates JAVA_OPTS and share set to off' do - component.release - expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_appmon_agent/agent/lib64/'\ - 'libdtagent.so=name=test-application-name_Monitoring,server=test-host-name') - expect(java_opts).to include('-Xshare:off') - end - - context do - - let(:configuration) { { 'default_agent_name' => 'different-agent-name' } } - - it 'updates JAVA_OPTS with configured agent name' do - component.release - expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_appmon_agent/agent/lib64/'\ - 'libdtagent.so=name=different-agent-name,server=test-host-name') - end - - end - end - - context do - before do - allow(services).to receive(:one_service?).with(/dynatrace/, 'server').and_return(true) - allow(services).to receive(:one_service?).with(/dynatrace/, 'tenant').and_return(false) - allow(services).to receive(:one_service?).with(/dynatrace/, 'tenanttoken').and_return(false) - allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'test-host-name', - 'profile' => 'test-profile' }) - end - - it 'updates JAVA_OPTS with custom profile' do - component.release - expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_appmon_agent/agent/lib64/'\ - 'libdtagent.so=name=test-application-name_test-profile,server=test-host-name') - end - - end -end From fd50c138579e54503ea25f0f8a1b02b6229866f2 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 14 Jul 2021 16:53:59 -0400 Subject: [PATCH 648/812] Polishing after #893 (#894) - Remove DynatraceAppmonAgent from the component list. This was missed when AppMon Agent was removed. - Fixes syntax error with missing `end` block - Fixes Rubocop violation for single line if blocks, use `cmd if expr` syntax intead - Adds referenced but missing method to pull the networkzone property from credentials - Adds docs for the networkzone property - Adds a unit test to validate that networkzone is passed in the URL when present in the binding --- config/components.yml | 1 - docs/framework-dynatrace_one_agent.md | 1 + .../framework/dynatrace_one_agent.rb | 14 +++++------ .../framework/dynatrace_one_agent_spec.rb | 25 +++++++++++++++++++ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/config/components.yml b/config/components.yml index e7e6c39230..fdfc151f54 100644 --- a/config/components.yml +++ b/config/components.yml @@ -51,7 +51,6 @@ frameworks: - "JavaBuildpack::Framework::ContrastSecurityAgent" - "JavaBuildpack::Framework::DatadogJavaagent" - "JavaBuildpack::Framework::Debug" - - "JavaBuildpack::Framework::DynatraceAppmonAgent" - "JavaBuildpack::Framework::DynatraceOneAgent" - "JavaBuildpack::Framework::ElasticApmAgent" - "JavaBuildpack::Framework::GoogleStackdriverDebugger" diff --git a/docs/framework-dynatrace_one_agent.md b/docs/framework-dynatrace_one_agent.md index 08d8739557..cf0d3cfa89 100644 --- a/docs/framework-dynatrace_one_agent.md +++ b/docs/framework-dynatrace_one_agent.md @@ -28,6 +28,7 @@ The credential payload of the service may contain the following entries: | `apitoken` | The token for integrating your Dynatrace environment with Cloud Foundry. You can find it in the deploy Dynatrace section within your environment. | `apiurl` | (Optional) The base URL of the Dynatrace API. If you are using Dynatrace Managed you will need to set this property to `https:///e//api`. If you are using Dynatrace SaaS you don't need to set this property. | `environmentid` | Your Dynatrace environment ID is the unique identifier of your Dynatrace environment. You can find it in the deploy Dynatrace section within your environment. +| `networkzone` | (Optional) Network zones are Dynatrace entities that represent your network structure. They help you to route the traffic efficiently, avoiding unnecessary traffic across data centers and network regions. Enter the network zone you wish to pass to the server during the OneAgent Download. | `skiperrors` | (Optional) The errors during agent download are skipped and the injection is disabled. Use this option at your own risk. Possible values are 'true' and 'false'. This option is disabled by default! ## Configuration diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index e171e9bda5..baeb939a1a 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -112,12 +112,10 @@ def supports? def agent_download_url download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ - "&bitness=64" \ + '&bitness=64' \ "&Api-Token=#{credentials[APITOKEN]}" - # - # setting networkzone parameter if it's configured - if networkzone? - download_uri += "&networkzone=#{networkzone_value}" + + download_uri += "&networkzone=#{networkzone}" if networkzone? ['latest', download_uri] end @@ -180,6 +178,10 @@ def expand(file) end end + def networkzone + credentials[NETWORKZONE] + end + def networkzone? credentials.key?(NETWORKZONE) end @@ -201,8 +203,6 @@ def unpack_agent(root) FileUtils.mv(root + 'agent', @droplet.sandbox) FileUtils.mv(root + 'manifest.json', @droplet.sandbox) end - end - end end diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 9126e2c8ed..4ded98c17a 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -92,6 +92,31 @@ end + context do + + before do + allow(services).to receive(:one_service?).with(/dynatrace/, 'apitoken', 'environmentid').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'environmentid' => 'test-environmentid', + 'apiurl' => 'test-apiurl', + 'apitoken' => 'test-apitoken', + 'networkzone' => 'test-network-zone' }) + + allow(application_cache).to receive(:get) + .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&' \ + 'Api-Token=test-apitoken&networkzone=test-network-zone') + .and_yield(Pathname.new('spec/fixtures/stub-dynatrace-one-agent.zip').open, false) + end + + it 'downloads Dynatrace agent zip with networkzone', + cache_fixture: 'stub-dynatrace-one-agent.zip' do + + component.compile + + expect(sandbox + 'agent/lib64/liboneagentloader.so').to exist + expect(sandbox + 'manifest.json').to exist + end + end + context do before do From 910546c72c4d74ea425bb82799b2e570e2579e78 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 19 Jul 2021 15:36:10 -0400 Subject: [PATCH 649/812] Document some packaging caveats which recently surfaced in #892 (#895) --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 1c66c9838b..04ec2f46bc 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,14 @@ $ bundle exec rake clean package VERSION=2.1 Creating build/java-buildpack-2.1.zip ``` +### Packaging Caveats + +1. When pinning versions, only the default JRE version is pinned. There is [special handling to package additional versions of a JRE](https://github.com/cloudfoundry/java-buildpack/blob/main/rakelib/dependency_cache_task.rb#L128-L144) and the way this works, it will pick the latest version at the time you package not at the time of the version's release. +2. The `index.yml` file for a dependencie is packaged in the buildpack cache when building offline buildpacks. The `index.yml` file isn't versioned with the release, so if you package an offline buildpack for an older release, it will pull the current `index.yml`, not the one from the time of the release. This can result in errors if a user tells the buildpack to install the latest version of a default dependency, because the latest version is calculated from the `index.yml` file which has more recent versions than what are packaged in the offline buildpack. Because of #1, this only impacts the default JRE. Non-default JREs always package the most recent version, which is also the most recent version in `index.yml` at the time you package the offline buildpack. +3. Because of #1 and #2, it is not present to accurately reproduce packages of the buildpack, after releases have been cut. If building pinning or offline buildpacks, it is suggested to build them as soon as possible after a release is cut and save the produced artifact. + +See [#892](https://github.com/cloudfoundry/java-buildpack/issues/892#issuecomment-880212806) for additional details. + ## Running Tests To run the tests, do the following: From 3a824b2cf33762598b4529bb1d62529170112a67 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 19 Jul 2021 17:06:29 -0400 Subject: [PATCH 650/812] Use docker creds in CI pipelines to avoid rate limits (#896) --- ci/auto-merge.yml | 2 ++ ci/package-test.yml | 2 ++ ci/unit-test.yml | 2 ++ ci/versions-json.yml | 2 ++ ci/versions-markdown.yml | 2 ++ ci/versions-yaml.yml | 2 ++ ci/versions.yml | 2 ++ 7 files changed, 14 insertions(+) diff --git a/ci/auto-merge.yml b/ci/auto-merge.yml index a1fbfe2625..cb2af56905 100644 --- a/ci/auto-merge.yml +++ b/ci/auto-merge.yml @@ -19,6 +19,8 @@ image_resource: type: registry-image source: repository: cfje/java-buildpack + username: ((docker-username)) + password: ((docker-password)) inputs: - name: downstream diff --git a/ci/package-test.yml b/ci/package-test.yml index 733e14ebf5..2c4cf3cdc9 100644 --- a/ci/package-test.yml +++ b/ci/package-test.yml @@ -19,6 +19,8 @@ image_resource: type: registry-image source: repository: cfje/java-buildpack + username: ((docker-username)) + password: ((docker-password)) inputs: - name: java-buildpack diff --git a/ci/unit-test.yml b/ci/unit-test.yml index b367ff13be..21e547d0ff 100644 --- a/ci/unit-test.yml +++ b/ci/unit-test.yml @@ -19,6 +19,8 @@ image_resource: type: registry-image source: repository: cfje/java-buildpack + username: ((docker-username)) + password: ((docker-password)) inputs: - name: java-buildpack diff --git a/ci/versions-json.yml b/ci/versions-json.yml index 69f283fa3d..8c35e603e4 100644 --- a/ci/versions-json.yml +++ b/ci/versions-json.yml @@ -19,6 +19,8 @@ image_resource: type: registry-image source: repository: cfje/java-buildpack + username: ((docker-username)) + password: ((docker-password)) inputs: - name: java-buildpack diff --git a/ci/versions-markdown.yml b/ci/versions-markdown.yml index e8b68817f9..bb43e2e0be 100644 --- a/ci/versions-markdown.yml +++ b/ci/versions-markdown.yml @@ -19,6 +19,8 @@ image_resource: type: registry-image source: repository: cfje/java-buildpack + username: ((docker-username)) + password: ((docker-password)) inputs: - name: java-buildpack diff --git a/ci/versions-yaml.yml b/ci/versions-yaml.yml index 46c45eb6aa..9ee7273d58 100644 --- a/ci/versions-yaml.yml +++ b/ci/versions-yaml.yml @@ -19,6 +19,8 @@ image_resource: type: registry-image source: repository: cfje/java-buildpack + username: ((docker-username)) + password: ((docker-password)) inputs: - name: java-buildpack diff --git a/ci/versions.yml b/ci/versions.yml index 4a0401f01a..d150ba46b2 100644 --- a/ci/versions.yml +++ b/ci/versions.yml @@ -19,6 +19,8 @@ image_resource: type: registry-image source: repository: cfje/java-buildpack + username: ((docker-username)) + password: ((docker-password)) inputs: - name: java-buildpack From 5254a19c94873854e1e43cb4bc9f5f6fdbfffce7 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 21 Jul 2021 15:00:38 -0400 Subject: [PATCH 651/812] Fix class count discrepancy when using DataDog agent. (#890) Resolves #887. This fix will go through the DataDog agent file and count the number of `.classdata` hidden classes. It then creates a shadow JAR file with the same number of fake classes in it. The Java buildpack's normal class counting mechanism will now see these classes and pick a correct class count. --- .../framework/datadog_javaagent.rb | 32 ++++++++++++++++-- spec/fixtures/stub-datadog-javaagent.jar | Bin 1288 -> 15478 bytes .../framework/datadog_javaagent_spec.rb | 18 +++++++--- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/framework/datadog_javaagent.rb b/lib/java_buildpack/framework/datadog_javaagent.rb index 2fe4cd5faa..8479d8e88a 100644 --- a/lib/java_buildpack/framework/datadog_javaagent.rb +++ b/lib/java_buildpack/framework/datadog_javaagent.rb @@ -27,7 +27,7 @@ class DatadogJavaagent < JavaBuildpack::Component::VersionedDependencyComponent def initialize(context) super(context) - @datadog_buildpack = File.exist? File.join(@droplet.root, 'datadog') + @datadog_buildpack = File.exist? File.join(@droplet.root, '.datadog') @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger DatadogJavaagent end @@ -35,7 +35,10 @@ def initialize(context) def compile @logger.error 'Datadog Buildpack is required, but not found' unless @datadog_buildpack - download_jar if @datadog_buildpack + return unless @datadog_buildpack + + download_jar + fix_class_count end # (see JavaBuildpack::Component::BaseComponent#release) @@ -63,6 +66,31 @@ def supports? apm_disabled = @application.environment['DD_APM_ENABLED'] == 'false' (api_key_defined && !apm_disabled) end + + # fixes issue where some classes are not counted by adding shadow class files + def fix_class_count + cnt = classdata_count(@droplet.sandbox + jar_name) + zipdir = "#{@droplet.sandbox}/datadog_fakeclasses" + zipfile = "#{@droplet.sandbox}/datadog_fakeclasses.jar" + + File.delete(zipfile) if File.exist? zipfile + FileUtils.rm_rf(zipdir) + FileUtils.mkdir_p(zipdir) + + 1.upto(cnt) do |i| + File.open("#{zipdir}/#{i}.class", 'w') do |f| + f.write(i.to_s) + end + end + + `cd #{zipdir} && zip -r #{zipfile} .` + FileUtils.rm_rf(zipdir) + end + + # count hidden class files in the agent JAR + def classdata_count(archive) + `unzip -l #{archive} | grep '\\(\\.classdata\\)$' | wc -l`.to_i + end end end end diff --git a/spec/fixtures/stub-datadog-javaagent.jar b/spec/fixtures/stub-datadog-javaagent.jar index 558673445672aa313d41c7168c02b9dbd42c653c..1f33a1b6a17e0e1d69fc0dfe2ecebca5c75375cf 100644 GIT binary patch literal 15478 zcmc&*O=w(I6rMI|HLY!8|4e^~ErnuJGNG*tX`x{8NJ6oYxs4m)bZ}U3?DYj^%WH#C5a^8_{Y;ew{gW!?u>oeYu{^ zcOR{YPh(?uZd>mk{Ll9u;D2Y=LI`)~{?;P@o$#lR!_7^W3nSC>Q=?6c7an}KB0dNs zf@sGmgqSPLPftxQmGg5`ij3YvjQZn@s@giUJYK_`llUa^!a#>xfox|jUpH4@yqOa6 zWGBcbuxN=QIIiQc8hFjF<~ORQVs&wlv+6-=j$LDpYp}XvtZ%qfLt*hRyLc=PvTB%y zwdNJ&2p8wER)Hpq>jc2i)|lmvgqRt%zZYQNTy;E-(glFm&|nLW%@?I(=&Y`Yh`V&U z17gLl)*N<&S#@KbC<%e)R!j2=zify@? zVKILZ4BmdUa)f^pr!6k(g-(1U@L~{V+FG^q6;rF%1(B2*zNi*-i8*{hnyg+=6&1Gz z&JErY#Z``R4gvN8C+LZqt})*6M7&5yYRFhQa2~~(M#zntX={3F{ajKYABK3vJM*OK zCKm22CGhyB%Zhfxa`}!{YPhwAyW~1dtCE$BdzYuMXt;){s5zW%fgESS&@VHSp9IJ` z;@IPq*bB{r16%f0l{xqfC3w8e(^mQ};|feuNEDkJeZ9`5w#Z&zkPiLFz)t z!M4hqHAW7O2gxag0yGbKp1jGskjfPC@I8I;+7`r_GIL^Q6cQ7=pkte6>KR!k2C?dm zTFrJ`rcYYyhGSb*p6cXAh1FbsV49eSTVmBtPt-H_T4mpe^;)Dk!>=ZMqoT*gL*pDRbDKYnm@MT0 zDW!^4YKG+Hj`Wqe;wl?ftm1ywQOmEFOg%G+#cbsWm;3}j<7Xz5vLdU_+&I&$E*)Z) zvsI*It=Y{D-JgY-i=uLTjmd-ybk$gEIGWf2y0;aK(W=tLWim;NoVosZ{-3AC=TBw715CkjnpnNc7&K++_^XYQ;>2y&9S27XFHl?s2;6q6JyK-zn20dc@q1#RS zUbvDje?MknT{BGWRg>{EafLsU*iO-QSbb73$~>R0W}-I1G~Ki-x0+ni9@(&LuXTkI z)5|yb)nD&UnNlj)?;t2s=9a145Mv4smrtr2B5uwEtvTT}ZfUdbGWt6V4o^H|gt?0Y z&dUa;z+X`Rw+3|OlqFurui1^I8+OCg=WX{gx8RnoH;h`1>2oaaZn%=i+HKp1dXl`$ z!KObXe9TYY7GK*tnL9iuv*qnMLdHY4FXtiWas#>F3MGyl^9VSccq{J!hgEREhx3TO zABO`jft)BdCHn!<$8qGq>*SzqeaX~hs|MR7;GHX$%^ zwqo-80QrwVjL2D&%LwDb@%l?!TrMEbn3coh=dD0C-rjX_XS_54Z698ox&o7y2NKWY zggJ2m^x#9aK;o9x42jJ)xw!E9xCr9!c}gkKWbal^05=j&uy+6faZytdHpV;zME7kA zX3)Vj*vA3((Wm1D6MO?~w0%fsFxFo%B|ZH$6rzMaY%?jM3NHZ_d`}6NVEf92fR#84 zI9%zI7dA{eZVe_mz;Z%ZMS0NaEeavu4CXNF(A_`8fa;dBycBp+ zz!h*PkV&@5hxm*z#iFp1|$& z*Hok;ePA=2&Sw!6$=a8xNZ~M@JN;V1%k% zl<}~EXO@4{1y*p$=@OX--MMp!)SaLtKC|e|kWDdH0H=e`W#N=z5@PiP&r_ayK2Ar= zH$>BjXa$yqztI!MOVBDmzN)287t~e2@{3F?foI%IU|DR3^-mNP~NL340AhzG>JSIT*ex&j69%J~wZEJPn=}h3M==#xg6%nVicBVX? p5A4uS8Te!y-OxtSj^(6QeNwJF`15}*H_m^3`g|_;B}dBT{sX72mkR&@ literal 1288 zcmWIWW@h1H00GuIdp9rxO0Y4=FeIj@=9TD&hHx@4uZ%t$5;@^)NNEK(10%~fMg|5J z5unNdoce{~`g1b#N-K0LEX;JxOo%j$1I;m#*bPH+-+EHrCx_3-I=2Urn z=H_H3!NOoSAqS%ytV7sfpz$ds;6TwU&Id;u$QBUB8ExWoP@^3bERp%8!5R6bIVpbm zB_4@osiApQnFR%@DZZ(CB^4!LbA5qH0faHkWn_|L#+9HXph-)B;jJTx35z~fNb(}V zEMW#@vmD@Np(QoK24f~PWP^LL8;s;`P_iSz-Et`Iet^$-Xc8ps1@v?xk79=fFsDM? zixM_4AxLrrT7or^AR-gp5*@fD3=B&eCla;_E7fiGjf%h#43FCtUvH diff --git a/spec/java_buildpack/framework/datadog_javaagent_spec.rb b/spec/java_buildpack/framework/datadog_javaagent_spec.rb index 185ac6ae7a..b79818b506 100644 --- a/spec/java_buildpack/framework/datadog_javaagent_spec.rb +++ b/spec/java_buildpack/framework/datadog_javaagent_spec.rb @@ -67,11 +67,11 @@ context 'when datadog buildpack is present' do before do - FileUtils.mkdir_p File.join(context[:droplet].root, 'datadog') + FileUtils.mkdir_p File.join(context[:droplet].root, '.datadog') end after do - FileUtils.rmdir File.join(context[:droplet].root, 'datadog') + FileUtils.rmdir File.join(context[:droplet].root, '.datadog') end it 'compile downloads datadog-javaagent JAR', cache_fixture: 'stub-datadog-javaagent.jar' do @@ -79,6 +79,16 @@ expect(sandbox + "datadog_javaagent-#{version}.jar").to exist end + it 'makes a jar with fake class files', cache_fixture: 'stub-datadog-javaagent.jar' do + component.compile + expect(sandbox + "datadog_javaagent-#{version}.jar").to exist + expect(sandbox + 'datadog_fakeclasses.jar').to exist + expect(sandbox + 'datadog_fakeclasses').not_to exist + + cnt = `unzip -l #{sandbox}/datadog_fakeclasses.jar | grep '\\(\\.class\\)$' | wc -l`.to_i + expect(cnt).to equal(34) + end + it 'release updates JAVA_OPTS' do component.release @@ -114,11 +124,11 @@ end before do - FileUtils.mkdir_p File.join(context[:droplet].root, 'datadog') + FileUtils.mkdir_p File.join(context[:droplet].root, '.datadog') end after do - FileUtils.rmdir File.join(context[:droplet].root, 'datadog') + FileUtils.rmdir File.join(context[:droplet].root, '.datadog') end it 'release updates JAVA_OPTS with env variable version' do From 70f89967aab82683d523f6c8caaedafe31bfef37 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 22 Jul 2021 09:41:53 -0400 Subject: [PATCH 652/812] Ensures compatibility with older and newer DataDog buildpacks. (#898) Checks for the DataDog to be installed into either `$HOME/.datadog` (new) or `$HOME/datadog` (old) locations. --- .../framework/datadog_javaagent.rb | 12 ++++--- .../framework/datadog_javaagent_spec.rb | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/java_buildpack/framework/datadog_javaagent.rb b/lib/java_buildpack/framework/datadog_javaagent.rb index 8479d8e88a..24fb07ea38 100644 --- a/lib/java_buildpack/framework/datadog_javaagent.rb +++ b/lib/java_buildpack/framework/datadog_javaagent.rb @@ -27,15 +27,14 @@ class DatadogJavaagent < JavaBuildpack::Component::VersionedDependencyComponent def initialize(context) super(context) - @datadog_buildpack = File.exist? File.join(@droplet.root, '.datadog') @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger DatadogJavaagent end # (see JavaBuildpack::Component::BaseComponent#compile) def compile - @logger.error 'Datadog Buildpack is required, but not found' unless @datadog_buildpack + @logger.error 'Datadog Buildpack is required, but not found' unless datadog_buildpack? - return unless @datadog_buildpack + return unless datadog_buildpack? download_jar fix_class_count @@ -43,7 +42,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - return unless @datadog_buildpack + return unless datadog_buildpack? java_opts = @droplet.java_opts java_opts.add_javaagent(@droplet.sandbox + jar_name) @@ -67,6 +66,11 @@ def supports? (api_key_defined && !apm_disabled) end + # determins if the datadog buildpack is present + def datadog_buildpack? + File.exist?(File.join(@droplet.root, '.datadog')) || File.exist?(File.join(@droplet.root, 'datadog')) + end + # fixes issue where some classes are not counted by adding shadow class files def fix_class_count cnt = classdata_count(@droplet.sandbox + jar_name) diff --git a/spec/java_buildpack/framework/datadog_javaagent_spec.rb b/spec/java_buildpack/framework/datadog_javaagent_spec.rb index b79818b506..398688572e 100644 --- a/spec/java_buildpack/framework/datadog_javaagent_spec.rb +++ b/spec/java_buildpack/framework/datadog_javaagent_spec.rb @@ -100,6 +100,41 @@ end end + context 'when datadog buildpack 4.22.0 (or older) is present' do + before do + FileUtils.mkdir_p File.join(context[:droplet].root, 'datadog') + end + + after do + FileUtils.rmdir File.join(context[:droplet].root, 'datadog') + end + + it 'compile downloads datadog-javaagent JAR', cache_fixture: 'stub-datadog-javaagent.jar' do + component.compile + expect(sandbox + "datadog_javaagent-#{version}.jar").to exist + end + + it 'makes a jar with fake class files', cache_fixture: 'stub-datadog-javaagent.jar' do + component.compile + expect(sandbox + "datadog_javaagent-#{version}.jar").to exist + expect(sandbox + 'datadog_fakeclasses.jar').to exist + expect(sandbox + 'datadog_fakeclasses').not_to exist + + cnt = `unzip -l #{sandbox}/datadog_fakeclasses.jar | grep '\\(\\.class\\)$' | wc -l`.to_i + expect(cnt).to equal(34) + end + + it 'release updates JAVA_OPTS' do + component.release + + expect(java_opts).to include( + "-javaagent:$PWD/.java-buildpack/datadog_javaagent/datadog_javaagent-#{version}.jar" + ) + expect(java_opts).to include('-Ddd.service=\"test-application-name\"') + expect(java_opts).to include('-Ddd.version=test-application-version') + end + end + context 'when datadog buildpack is not present' do it 'compile downloads datadog-javaagent JAR', cache_fixture: 'stub-datadog-javaagent.jar' do component.compile From 20da5f1244b1b89c5163ebad836a33c9249243be Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 18 Aug 2021 13:09:02 -0400 Subject: [PATCH 653/812] Update README.md Add a link to DataDog framework docs. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 04ec2f46bc..facf5b16ff 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ The buildpack supports extension through the use of Git repository forking. The * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) * [Container Security Provider](docs/framework-container_security_provider.md) ([Configuration](docs/framework-container_security_provider.md#configuration)) * [Contrast Security Agent](docs/framework-contrast_security_agent.md) ([Configuration](docs/framework-contrast_security_agent.md#configuration)) + * [DataDog](docs/framework-datadog_javaagent.md) ([Configuration](docs/framework-datadog_javaagent.md#configuration) * [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration)) * [Elastic APM Agent](docs/framework-elastic_apm_agent.md) ([Configuration](docs/framework-elastic_apm_agent.md#configuration)) * [Dynatrace SaaS/Managed OneAgent](docs/framework-dynatrace_one_agent.md) ([Configuration](docs/framework-dynatrace_one_agent.md#configuration)) From 91aefacfabd8693df6fbcb9347c6316cd3179133 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 20 Sep 2021 14:59:19 -0400 Subject: [PATCH 654/812] Drop Java 16 and add Java 17 (#901) Signed-off-by: Daniel Mikusa --- rakelib/dependency_cache_task.rb | 2 +- rakelib/versions_task.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 7e600bde06..0466338843 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -138,7 +138,7 @@ def configurations(component_id, configuration, sub_component_id = nil) if component_id == 'open_jdk_jre' && sub_component_id == 'jre' c1 = configuration.clone - c1['version'] = '16.+' + c1['version'] = '17.+' configurations << c1 end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 0ca08ce06f..1919af953e 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -72,7 +72,7 @@ def initialize 'jprofiler_profiler' => 'JProfiler Profiler', 'jre' => 'OpenJDK JRE', 'jre-11' => 'OpenJDK JRE 11', - 'jre-16' => 'OpenJDK JRE 16', + 'jre-17' => 'OpenJDK JRE 17', 'jrebel_agent' => 'JRebel Agent', 'jvmkill_agent' => 'jvmkill Agent', 'lifecycle_support' => 'Tomcat Lifecycle Support', @@ -168,8 +168,8 @@ def configurations(component_id, configuration, sub_component_id = nil) if component_id == 'open_jdk_jre' && sub_component_id == 'jre' c1 = configuration.clone - c1['sub_component_id'] = 'jre-16' - c1['version'] = '16.+' + c1['sub_component_id'] = 'jre-17' + c1['version'] = '17.+' configurations << c1 end From c57b98039ebf2fb60d716cd745503bc0cd1fd2f5 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 6 Oct 2021 13:34:19 -0400 Subject: [PATCH 655/812] Modify default Tomcat configuration to include HTTP/2 support (#906) This commit will enable HTTP/2 upgrade support, specifically H2C, in the Tomcat configuration that is generated by the buildpack. This will enable HTTP/2 by default. It cannot be disabled, unless you use the Java buildpack's feature to use external Tomcat configuration. The impact should be minimal as you will still retain full HTTP/1.1 support, HTTP/2 will not be forced on clients, and a client would need to request HTTP/2. This commit should also support Java 8+ because we are using H2C, so the additional TLS requirements that precipitate using Java 9+ do not apply. Full HTTP/2 support requires running a version of Cloud Foundry that also includes support for HTTP/2, or use via the container to container network. Signed-off-by: Daniel Mikusa --- resources/tomcat/conf/server.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/tomcat/conf/server.xml b/resources/tomcat/conf/server.xml index 850f74a604..a75866fb1a 100644 --- a/resources/tomcat/conf/server.xml +++ b/resources/tomcat/conf/server.xml @@ -19,7 +19,9 @@ - + + + From 837e45ee99fe69cdfcac77983ca95ad598ef6053 Mon Sep 17 00:00:00 2001 From: Allon Murienik Date: Tue, 12 Oct 2021 20:56:49 +0300 Subject: [PATCH 656/812] Rename framework-seeker-security-provider.md (#910) Rename framework-seeker-security-provider.md to framework-seeker_security_provider.md to follow the convention of the other files in the docs folder. As a "side bonus", this will fix the broken link to it from README.md Closes #909 --- ...security-provider.md => framework-seeker_security_provider.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{framework-seeker-security-provider.md => framework-seeker_security_provider.md} (100%) diff --git a/docs/framework-seeker-security-provider.md b/docs/framework-seeker_security_provider.md similarity index 100% rename from docs/framework-seeker-security-provider.md rename to docs/framework-seeker_security_provider.md From ba248749ae29f049777dfe6534abf16a81fca70b Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 18 Oct 2021 13:25:05 -0400 Subject: [PATCH 657/812] Relax escaping of values to enable limited access to the shell for AppDynamnics config (#911) [Previous PRs escaped configuration values for AppD](https://github.com/cloudfoundry/java-buildpack/pull/870). This was done to support things like names with spaces and other characters that, if used, would result in a broken start command. The PR broke a use case which was documented for the node or tier name. In some cases, you may want to set the node or tier name to a dynamic value that is loaded at runtime so that you can incorporate things like the application instance index. For example `DCX:$(echo $VCAP_APPLICATION | jq -r '.application_name'):$(echo $VCAP_APPLICATION | jq -r '.instance_index')`. This new PR will use `Shellwords.escape(..)` on the value for all properties unless that property value contains what looks like a subshell `$(..)` or environment variable `${..}` reference. If it looks like a subshell or env variable is being referenced, we will not escape but just wrap the value in escaped quotes. We wrap it in escaped quotes in case the shell variable or subshell returns something which includes spaces. This is not perfect though, and you need to be careful if using subshell/env variables, you should ensure the output is properly escaped. For example: - `DCX:$(echo $VCAP_APPLICATION | jq -r '.application_name'):$(echo $VCAP_APPLICATION | jq -r '.instance_index')` - `$(echo 'Hello world!') and stuff` becomes `\"$(echo 'Hello world!') and stuff\"` - `--> ${SOME_VAR} <--` becomes `\"--> ${SOME_VAR} <--\"` Signed-off-by: Daniel Mikusa --- docs/framework-app_dynamics_agent.md | 2 +- .../framework/app_dynamics_agent.rb | 26 +++++++----- .../framework/app_dynamics_agent_spec.rb | 40 +++++++++++++++++++ 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/docs/framework-app_dynamics_agent.md b/docs/framework-app_dynamics_agent.md index c0f76c135c..e1ec4a53e0 100644 --- a/docs/framework-app_dynamics_agent.md +++ b/docs/framework-app_dynamics_agent.md @@ -26,7 +26,7 @@ When binding AppDynamics using a user-provided service, it must have name or tag | `node-name` | (Optional) the application's node name | `tier-name` | (Optional) the application's tier name -To provide more complex values such as the `tier-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `tier-name` could be set with a value of `Tier-$(expr "$VCAP_APPLICATION" : '.*instance_index[": ]*\([[:digit:]]*\).*')` to calculate a value from the Cloud Foundry instance index. +To provide more complex values such as the `tier-name`, using the interactive mode when creating a user-provided service will manage the character escaping automatically. For example, the default `tier-name` could be set with a value of `Tier-$(expr "${VCAP_APPLICATION}" : '.*instance_index[": ]*\([[:digit:]]*\).*')` to calculate a value from the Cloud Foundry instance index. **Note:** Some credentials were previously marked as "(Optional)" as requirements have changed across versions of the AppDynamics agent. Please see the [AppDynamics Java Agent Configuration Properties][] for the version of the agent used by your application for more details. diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index dada5ce87b..f9d41c0198 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -86,35 +86,35 @@ def supports? private_constant :FILTER def application_name(java_opts, credentials) - name = Shellwords.escape(@application.details['application_name']) + name = escape(@application.details['application_name']) name = @configuration['default_application_name'] if @configuration['default_application_name'] - name = Shellwords.escape(credentials['application-name']) if credentials['application-name'] + name = escape(credentials['application-name']) if credentials['application-name'] java_opts.add_system_property('appdynamics.agent.applicationName', name.to_s) end def account_access_key(java_opts, credentials) account_access_key = credentials['account-access-key'] || credentials.dig('account-access-secret', 'secret') - account_access_key = Shellwords.escape(account_access_key) + account_access_key = escape(account_access_key) java_opts.add_system_property 'appdynamics.agent.accountAccessKey', account_access_key if account_access_key end def account_name(java_opts, credentials) account_name = credentials['account-name'] - java_opts.add_system_property 'appdynamics.agent.accountName', Shellwords.escape(account_name) if account_name + java_opts.add_system_property 'appdynamics.agent.accountName', escape(account_name) if account_name end def host_name(java_opts, credentials) host_name = credentials['host-name'] raise "'host-name' credential must be set" unless host_name - java_opts.add_system_property 'appdynamics.controller.hostName', Shellwords.escape(host_name) + java_opts.add_system_property 'appdynamics.controller.hostName', escape(host_name) end def node_name(java_opts, credentials) name = @configuration['default_node_name'] - name = Shellwords.escape(credentials['node-name']) if credentials['node-name'] + name = escape(credentials['node-name']) if credentials['node-name'] java_opts.add_system_property('appdynamics.agent.nodeName', name.to_s) end @@ -130,15 +130,15 @@ def ssl_enabled(java_opts, credentials) end def tier_name(java_opts, credentials) - name = Shellwords.escape(@application.details['application_name']) + name = escape(@application.details['application_name']) name = @configuration['default_tier_name'] if @configuration['default_tier_name'] - name = Shellwords.escape(credentials['tier-name']) if credentials['tier-name'] + name = escape(credentials['tier-name']) if credentials['tier-name'] java_opts.add_system_property('appdynamics.agent.tierName', name.to_s) end def unique_host_name(java_opts) - name = Shellwords.escape(@application.details['application_name']) + name = escape(@application.details['application_name']) name = @configuration['default_unique_host_name'] if @configuration['default_unique_host_name'] java_opts.add_system_property('appdynamics.agent.uniqueHostId', name.to_s) @@ -180,6 +180,14 @@ def save_cfg_file(file, conf_file) FileUtils.cp_r file, target_directory + '/conf/' + conf_file end end + + def escape(value) + if /\$[\(\{][^\)\}]+[\)\}]/ =~ value + "\\\"#{value}\\\"" + else + Shellwords.escape(value) + end + end end end end diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index f8f988d567..cecf5d2b1e 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -92,6 +92,26 @@ end end + context do + let(:credentials) { super().merge 'tier-name' => '--> ${SOME_VAR} <--' } + + it 'adds tier_name from credentials with shell variable in it to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dappdynamics.agent.tierName=\"--> ${SOME_VAR} <--\"') + end + end + + context do + let(:credentials) { super().merge 'tier-name' => '$(echo \'Hello World!\') and stuff' } + + it 'adds tier_name from credentials with subshell in it to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dappdynamics.agent.tierName=\"$(echo \'Hello World!\') and stuff\"') + end + end + context do let(:credentials) { super().merge 'application-name' => 'another-test application-name' } @@ -102,6 +122,26 @@ end end + context do + let(:credentials) { super().merge 'application-name' => '$(echo \'Hello World!\') and stuff' } + + it 'adds application_name from credentials with subshell in value to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dappdynamics.agent.applicationName=\"$(echo \'Hello World!\') and stuff\"') + end + end + + context do + let(:credentials) { super().merge 'application-name' => 'Name ${MY_APP_NAME}' } + + it 'adds application_name from credentials with env variable in value to JAVA_OPTS if specified' do + component.release + + expect(java_opts).to include('-Dappdynamics.agent.applicationName=\"Name ${MY_APP_NAME}\"') + end + end + context do let(:configuration) do { 'default_tier_name' => nil, From b5bfccb5db079849ba315e93a01869da6c535d30 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 18 Oct 2021 13:25:35 -0400 Subject: [PATCH 658/812] Version matcher now prefers a specific match over a partial match (#907) Previous to this commit, if you have two versions say `3.1.1` and `3.1.1_BETA` the version matcher would incorrectly select `3.1.1_BETA`. It would behave as if a wildcard was present even though it's not present. This commit ensures that the same scenario will select version `3.1.1`, which is an exact match for the version requested. This may result in a difference of behavior for some users. If you are impacted by this, you need to switch your requested version to `3.1.1_+`. Using the scenario above, this will return `3.1.1_BETA`. Signed-off-by: Daniel Mikusa --- .../repository/version_resolver.rb | 23 ++++++++++++------- .../repository/version_resolver_spec.rb | 12 ++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/lib/java_buildpack/repository/version_resolver.rb b/lib/java_buildpack/repository/version_resolver.rb index 6d6d25838e..6d9beb1db3 100644 --- a/lib/java_buildpack/repository/version_resolver.rb +++ b/lib/java_buildpack/repository/version_resolver.rb @@ -76,18 +76,25 @@ def safe_candidate_version(candidate_version) end def matches?(tokenized_candidate_version, tokenized_version) + wildcard_matched = false (0..3).all? do |i| - tokenized_candidate_version[i].nil? || as_regex(tokenized_candidate_version[i]) =~ tokenized_version[i] - end - end + next true if wildcard_matched || tokenized_candidate_version[i].nil? && tokenized_version[i].nil? - def as_regex(version) - /^#{version.gsub(JavaBuildpack::Util::TokenizedVersion::WILDCARD, '.*')}/ - end + next false if tokenized_candidate_version[i].nil? && !tokenized_version[i].nil? - end + if tokenized_candidate_version[i] == JavaBuildpack::Util::TokenizedVersion::WILDCARD + wildcard_matched = true + next true + end - end + if tokenized_candidate_version[i].end_with?(JavaBuildpack::Util::TokenizedVersion::WILDCARD) + next !tokenized_version[i].nil? && tokenized_version[i].start_with?(tokenized_candidate_version[i][0..-2]) + end + tokenized_candidate_version[i] == tokenized_version[i] + end + end + end + end end end diff --git a/spec/java_buildpack/repository/version_resolver_spec.rb b/spec/java_buildpack/repository/version_resolver_spec.rb index be79020866..3193456fcc 100644 --- a/spec/java_buildpack/repository/version_resolver_spec.rb +++ b/spec/java_buildpack/repository/version_resolver_spec.rb @@ -69,6 +69,18 @@ expect(described_class.resolve(tokenized_version('2.0.+'), versions)).to eq(tokenized_version('2.0.0')) end + it 'picks an exact match over a partial match' do + versions = %w[3.1.1 3.1.1_BETA 3.1.1_BETA.2 3.1.2 3.2.0] + expect(described_class.resolve(tokenized_version('3.1.1'), versions)).to eq(tokenized_version('3.1.1')) + expect(described_class.resolve(tokenized_version('3.1.1_BETA'), versions)).to eq(tokenized_version('3.1.1_BETA')) + end + + it 'picks the latest including qualifiers' do + versions = %w[3.1.1 3.1.1_BETA 3.1.1_BETA.2 3.1.2 3.2.0] + expect(described_class.resolve(tokenized_version('3.1.1_+'), versions)).to eq(tokenized_version('3.1.1_BETA.2')) + expect(described_class.resolve(tokenized_version('3.1.1_BE+'), versions)).to eq(tokenized_version('3.1.1_BETA.2')) + end + def tokenized_version(s) JavaBuildpack::Util::TokenizedVersion.new(s) end From 75d663b28eaa3092b1dcdef8c7d24fed5a53593f Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 18 Oct 2021 13:25:49 -0400 Subject: [PATCH 659/812] Shell escape the value of Elastic APM custom properties (#908) The current behavior is for no escaping to occur. This if you use a value like `"object_name[java.lang:type=Memory] attribute[HeapMemoryUsage:metric_name=test_heap_metric]"` (as we see in #786), the literal value is inserted into a system property and the space (among other characters) breaks the start command. This change will use `Shellwords.escape(..)` the value for every custom property unless that property value contains what looks like a subshell `$(..)` or environment variable `${..}` reference. If it looks like a subshell or env variable is being referenced, we will not escape just wrap the value in escaped quotes. We wrap it in escaped quotes in case the shell variable or subshell returns something which includes spaces. This is not perfect though, and you need to be careful if using subshell/env variables, you should ensure the output is properly escaped. For example: - `object_name[java.lang:type=Memory] attribute[HeapMemoryUsage:metric_name=test_heap_metric]` becomes `object_name\[java.lang:type\=Memory\]\ attribute\[HeapMemoryUsage:metric_name\=test_heap_metric\]` - `$(echo 'Hello world!') and stuff` becomes `\"$(echo 'Hello world!') and stuff\"` - `--> ${SOME_VAR} <--` becomes `\"--> ${SOME_VAR} <--\"` Signed-off-by: Daniel Mikusa --- docs/framework-elastic_apm_agent.md | 2 +- lib/java_buildpack/framework/elastic_apm_agent.rb | 8 +++++++- .../framework/elastic_apm_agent_spec.rb | 12 +++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/framework-elastic_apm_agent.md b/docs/framework-elastic_apm_agent.md index 8d1cf11ad2..55f09c5d15 100644 --- a/docs/framework-elastic_apm_agent.md +++ b/docs/framework-elastic_apm_agent.md @@ -21,7 +21,7 @@ When binding Elastic APM using a user-provided service, it must have name or tag | ---- | ----------- | `server_urls` | The URLs for the Elastic APM Server. They must be fully qualified, including protocol (http or https) and port. | `secret_token` (Optional)| This string is used to ensure that only your agents can send data to your APM server. Both the agents and the APM server have to be configured with the same secret token. Use if APM Server requires a token. -| `***` (Optional) | Any additional entries will be applied as a system property appended to `-Delastic.apm.` to allow full configuration of the agent. See [Configuration of Elastic Agent][]. +| `***` (Optional) | Any additional entries will be applied as a system property appended to `-Delastic.apm.` to allow full configuration of the agent. See [Configuration of Elastic Agent][]. Values are shell-escaped by default, but do have limited support, use with caution, for incorporating subshells (i.e. `$(some-cmd)`) and accessing environment variables (i.e. `${SOME_VAR}`). ### Creating an Elastic APM USer Provided Service diff --git a/lib/java_buildpack/framework/elastic_apm_agent.rb b/lib/java_buildpack/framework/elastic_apm_agent.rb index fb25d05775..ba613f374a 100644 --- a/lib/java_buildpack/framework/elastic_apm_agent.rb +++ b/lib/java_buildpack/framework/elastic_apm_agent.rb @@ -15,6 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +require 'shellwords' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' @@ -89,7 +90,12 @@ def apply_user_configuration(credentials, configuration) def write_java_opts(java_opts, configuration) configuration.each do |key, value| - java_opts.add_system_property("elastic.apm.#{key}", value) + if /\$[\(\{][^\)\}]+[\)\}]/ =~ value + # we need \" because this is a system property which ends up inside `JAVA_OPTS` which is already quoted + java_opts.add_system_property("elastic.apm.#{key}", "\\\"#{value}\\\"") + else + java_opts.add_system_property("elastic.apm.#{key}", Shellwords.escape(value)) + end end end diff --git a/spec/java_buildpack/framework/elastic_apm_agent_spec.rb b/spec/java_buildpack/framework/elastic_apm_agent_spec.rb index 014cf67c63..9b74ddaab0 100644 --- a/spec/java_buildpack/framework/elastic_apm_agent_spec.rb +++ b/spec/java_buildpack/framework/elastic_apm_agent_spec.rb @@ -60,10 +60,16 @@ end it 'updates JAVA_OPTS with additional options' do + val = 'object_name[java.lang:type=Memory] attribute[HeapMemoryUsage:metric_name=test_heap_metric]' + shell = '$(echo \'Hello world!\') and stuff' + var = '--> ${SOME_VAR} <--' allow(services).to receive(:find_service).and_return('credentials' => { 'secret_token' => 'test-secret_token', 'server_urls' => 'different-serverurl', 'service_name' => 'different-name', - 'foo' => 'bar' }) + 'foo' => 'bar', + 'capture_jmx_metrics' => val, + 'sub' => shell, + 'var' => var }) component.release @@ -71,6 +77,10 @@ expect(java_opts).to include('-Delastic.apm.server_urls=different-serverurl') expect(java_opts).to include('-Delastic.apm.service_name=different-name') expect(java_opts).to include('-Delastic.apm.foo=bar') + escaped = 'object_name\[java.lang:type\=Memory\]\ attribute\[HeapMemoryUsage:metric_name\=test_heap_metric\]' + expect(java_opts).to include("-Delastic.apm.capture_jmx_metrics=#{escaped}") + expect(java_opts).to include('-Delastic.apm.sub=\"$(echo \'Hello world!\') and stuff\"') + expect(java_opts).to include('-Delastic.apm.var=\"--> ${SOME_VAR} <--\"') end end From 8b16938baf87dd07e354a85599a60fb33e4e1464 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Fri, 22 Oct 2021 13:48:32 -0400 Subject: [PATCH 660/812] Adds CVE & Release note links to generated version tables (#912) - Adds CVE & Release Notes links for dependencies used by the Java buildpack - Note links are mostly static and embedded in the task - Future work may be done to pull note links from other sources such as `config/` Signed-off-by: Daniel Mikusa --- rakelib/versions_task.rb | 96 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 8 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 1919af953e..3a16bcfeb9 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -29,6 +29,7 @@ module Package + # rubocop:disable Metrics/ClassLength class VersionsTask < Rake::TaskLib include Package @@ -95,10 +96,85 @@ def initialize 'your_kit_profiler' => 'YourKit Profiler' }.freeze + NOTE_LINKS = { + 'access_logging_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'agent' => { 'cve' => '', 'release' => '' }, + 'app_dynamics_agent' => { 'cve' => '', + 'release' => '[Release Notes](https://docs.appdynamics.com/4.5.x/en/product-and-' \ + 'release-announcements/release-notes/language-agent-notes/java-agent-notes)' }, + 'azure_application_insights_agent' => { 'cve' => '', 'release' => '' }, + 'clean_up' => { 'cve' => '', 'release' => '' }, + 'client_certificate_mapper' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'container_customizer' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'container_security_provider' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'contrast_security_agent' => + { 'cve' => '', + 'release' => '[Release Notes](https://docs.contrastsecurity.com/en/java-agent-release-notes.html)' }, + 'datadog_javaagent' => { 'cve' => '', + 'release' => '[Release Notes](https://github.com/DataDog/dd-trace-java/releases)' }, + 'dynatrace_one_agent' => + { 'cve' => '', + 'release' => '[Release Notes](https://www.dynatrace.com/support/help/whats-new/release-notes/#oneagent)' }, + 'elastic_apm_agent' => + { 'cve' => '', + 'release' => '[Release Notes](https://www.elastic.co/guide/en/apm/agent/java/current/release-notes.html)' }, + 'geode_store' => { 'cve' => '', 'release' => '' }, + 'google_stackdriver_debugger' => + { 'cve' => '', + 'release' => '[Release Notes](https://cloud.google.com/debugger/docs/release-notes)' }, + 'google_stackdriver_profiler' => + { 'cve' => '', + 'release' => '[Release Notes](https://cloud.google.com/profiler/docs/release-notes)' }, + 'groovy' => { 'cve' => '', 'release' => '[Release Notes](http://www.groovy-lang.org/releases.html)' }, + 'introscope_agent' => { 'cve' => '', 'release' => '' }, + 'jacoco_agent' => { 'cve' => '', 'release' => '[Release Notes](https://github.com/jacoco/jacoco/releases)' }, + 'jprofiler_profiler' => + { 'cve' => '', + 'release' => '[ChangeLog](https://www.ej-technologies.com/download/jprofiler/changelog.html)' }, + 'jre' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2021.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u312/)' }, + 'jre-11' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2021.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.13/)' }, + 'jre-17' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2021.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.1/)' }, + 'jrebel_agent' => { 'cve' => '', 'release' => '[ChangeLog](https://www.jrebel.com/products/jrebel/changelog)' }, + 'jvmkill_agent' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'lifecycle_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'logging_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'luna_security_provider' => + { 'cve' => '', + 'release' => + '[Release Notes](https://www.thalesdocs.com/gphsm/luna/7/docs/network/Content/CRN/Luna/CRN_Luna.htm)' }, + 'maria_db_jdbc' => + { 'cve' => '', + 'release' => '[Release Notes](https://mariadb.com/kb/en/mariadb-connector-j-274-release-notes/)' }, + 'memory_calculator' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'metric_writer' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'new_relic_agent' => + { 'cve' => '', + 'release' => + '[Release Notes](https://docs.newrelic.com/docs/release-notes/agent-release-notes/java-release-notes/)' }, + 'postgresql_jdbc' => { 'cve' => '', + 'release' => '[ChangeLog](https://jdbc.postgresql.org/documentation/changelog.html)' }, + 'protect_app_security_provider' => { 'cve' => '', 'release' => '' }, + 'redis_store' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'riverbed_appinternals_agent' => { 'cve' => '', 'release' => '' }, + 'sealights_agent' => { 'cve' => '', 'release' => '' }, + 'sky_walking_agent' => { 'cve' => '', + 'release' => '[ChangeLog](https://github.com/apache/skywalking/tree/master/changes)' }, + 'spring_auto_reconfiguration' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, + 'spring_boot_cli' => { 'cve' => '', 'release' => '' }, + 'takipi_agent' => { 'cve' => '', 'release' => '[Release Notes](https://doc.overops.com/docs/whats-new)' }, + 'tomcat' => { 'cve' => '[Security](https://tomcat.apache.org/security-9.html)', + 'release' => '[ChangeLog](https://tomcat.apache.org/tomcat-9.0-doc/changelog.html)' }, + 'your_kit_profiler' => { 'cve' => '', + 'release' => '[Release Notes](https://www.yourkit.com/download/yjp_2021_3_builds.jsp)' } + }.freeze + PLATFORM_PATTERN = /\{platform\}/.freeze private_constant :ARCHITECTURE_PATTERN, :DEFAULT_REPOSITORY_ROOT_PATTERN, :NAME_MAPPINGS, - :PLATFORM_PATTERN + :PLATFORM_PATTERN, :NOTE_LINKS def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at @@ -218,7 +294,9 @@ def dependency_versions 'id' => id, 'name' => name, 'uri' => uri, - 'version' => version + 'version' => version, + 'cve_link' => NOTE_LINKS[id]['cve'], + 'release_notes_link' => NOTE_LINKS[id]['release'] } end end @@ -253,7 +331,8 @@ def version_task rows = v['dependencies'] .sort_by { |dependency| dependency['name'].downcase } - .map { |dependency| [dependency['name'], dependency['version']] } + .map { |dependency| [dependency['name'], dependency['version'], + dependency['cve_link'], dependency['release_notes_link']] } puts Terminal::Table.new title: "Java Buildpack #{v['buildpack']}", rows: rows end @@ -263,20 +342,20 @@ def version_json_task desc 'Display the versions of buildpack dependencies in JSON form' task json: [] do puts JSON.pretty_generate(versions['dependencies'] - .sort_by { |dependency| dependency['name'].downcase } - .map { |dependency| "#{dependency['name']} #{dependency['version']}" }) + .sort_by { |dependency| dependency['name'].downcase }) end end def version_markdown_task desc 'Display the versions of buildpack dependencies in Markdown form' task markdown: [] do - puts '| Dependency | Version |' - puts '| ---------- | ------- |' + puts '| Dependency | Version | CVEs | Release Notes |' + puts '| ---------- | ------- | ---- | ------------- |' versions['dependencies'] .sort_by { |dependency| dependency['name'].downcase } - .each { |dependency| puts "| #{dependency['name']} | `#{dependency['version']}` |" } + .each { |dependency| puts "| #{dependency['name']} | `#{dependency['version']}` |" \ + "#{dependency['cve_link']} | #{dependency['release_notes_link']} |" } end end @@ -295,5 +374,6 @@ def versions end end + # rubocop:enable Metrics/ClassLength end From 11e457b8dd30dcba5ea8232b7d5c4ccbcd2781ec Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Fri, 22 Oct 2021 14:19:21 -0400 Subject: [PATCH 661/812] Fixes some Rubocop complaints (#913) Signed-off-by: Daniel Mikusa --- rakelib/versions_task.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 3a16bcfeb9..1156890a7d 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -331,8 +331,9 @@ def version_task rows = v['dependencies'] .sort_by { |dependency| dependency['name'].downcase } - .map { |dependency| [dependency['name'], dependency['version'], - dependency['cve_link'], dependency['release_notes_link']] } + .map do |dependency| + [dependency['name'], dependency['version'], dependency['cve_link'], dependency['release_notes_link']] + end puts Terminal::Table.new title: "Java Buildpack #{v['buildpack']}", rows: rows end @@ -354,8 +355,10 @@ def version_markdown_task versions['dependencies'] .sort_by { |dependency| dependency['name'].downcase } - .each { |dependency| puts "| #{dependency['name']} | `#{dependency['version']}` |" \ - "#{dependency['cve_link']} | #{dependency['release_notes_link']} |" } + .each do |dependency| + puts "| #{dependency['name']} | `#{dependency['version']}` |" \ + "#{dependency['cve_link']} | #{dependency['release_notes_link']} |" + end end end From 2efee96b61ec84a5b3fd1ddb59bc15c5024f94b9 Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Thu, 18 Nov 2021 15:26:46 +0100 Subject: [PATCH 662/812] Fixed case in networkzone query parameter (#915) --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index baeb939a1a..0b919012f9 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -115,7 +115,7 @@ def agent_download_url '&bitness=64' \ "&Api-Token=#{credentials[APITOKEN]}" - download_uri += "&networkzone=#{networkzone}" if networkzone? + download_uri += "&networkZone=#{networkzone}" if networkzone? ['latest', download_uri] end From 24a365fd227092ad0c06869f0f6637f4c92e9e60 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Fri, 10 Dec 2021 14:02:58 -0500 Subject: [PATCH 663/812] Bump JProfiler to 12.x branch (#916) - Version bump was requeste by users - Version 11.x has been EOL'd - Version 11 is still on the downloads server. If you need to stick with 11.x, you may set `JBP_CONFIG_JPROFILER_PROFILER_VERSION` to `11.+`. Signed-off-by: Daniel Mikusa --- config/jprofiler_profiler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/jprofiler_profiler.yml b/config/jprofiler_profiler.yml index 953b0cca0b..ad07cf4281 100644 --- a/config/jprofiler_profiler.yml +++ b/config/jprofiler_profiler.yml @@ -15,7 +15,7 @@ # JMX configuration --- -version: 11.+ +version: 12.+ repository_root: https://download.run.pivotal.io/jprofiler enabled: false nowait: true From 0cfed5c841833b855ce0b8e28c06c6b7907a9995 Mon Sep 17 00:00:00 2001 From: BenjaminPerryRoss Date: Sun, 12 Dec 2021 07:33:24 -0800 Subject: [PATCH 664/812] Update default geode-store version to 1.13.4 (#917) --- config/tomcat.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index 909080859e..bab03b0307 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -41,6 +41,6 @@ redis_store: connection_pool_size: 2 geode_store: # The version of Geode Store must be less than or equal to your Tanzu Gemfire for VMs version to ensure compatibility. - # The Geode Store version is pinned to 1.11.0 to be compatible with the most commonly used versions of Tanzu Gemfire for VMs. - version: 1.11.0 + # The Geode Store version is pinned to 1.13.4 to be compatible with the most commonly used versions of Tanzu Gemfire for VMs. + version: 1.13.4 repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 151eef13a5107090ab2ac9b8f6588b5b76120d1e Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Sun, 12 Dec 2021 14:04:57 -0500 Subject: [PATCH 665/812] Fixes test failure from #915 (#918) This PR caused a test failure, this PR fixes it. https://github.com/cloudfoundry/java-buildpack/pull/915 Signed-off-by: Daniel Mikusa --- spec/java_buildpack/framework/dynatrace_one_agent_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index 4ded98c17a..d2025b254a 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -103,7 +103,7 @@ allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&' \ - 'Api-Token=test-apitoken&networkzone=test-network-zone') + 'Api-Token=test-apitoken&networkZone=test-network-zone') .and_yield(Pathname.new('spec/fixtures/stub-dynatrace-one-agent.zip').open, false) end From 02aeb370524aa03fda3d0f2b1f5b1d4f07b91f7c Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 13 Dec 2021 11:49:50 -0500 Subject: [PATCH 666/812] Add release notes link for Azure App Insights (#920) Signed-off-by: Daniel Mikusa --- rakelib/versions_task.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 1156890a7d..da308f579e 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -102,7 +102,9 @@ def initialize 'app_dynamics_agent' => { 'cve' => '', 'release' => '[Release Notes](https://docs.appdynamics.com/4.5.x/en/product-and-' \ 'release-announcements/release-notes/language-agent-notes/java-agent-notes)' }, - 'azure_application_insights_agent' => { 'cve' => '', 'release' => '' }, + 'azure_application_insights_agent' => + { 'cve' => '', + 'release' => '[Release Notes](https://github.com/Microsoft/ApplicationInsights-Java/releases)' }, 'clean_up' => { 'cve' => '', 'release' => '' }, 'client_certificate_mapper' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, 'container_customizer' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, From 2fc6571d34698005c8842fb5f981491b44fd5889 Mon Sep 17 00:00:00 2001 From: Ben Ross Date: Fri, 17 Dec 2021 09:18:19 -0800 Subject: [PATCH 667/812] Update geode-store version to 1.12.4 --- config/tomcat.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index bab03b0307..f20f1411ef 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -41,6 +41,6 @@ redis_store: connection_pool_size: 2 geode_store: # The version of Geode Store must be less than or equal to your Tanzu Gemfire for VMs version to ensure compatibility. - # The Geode Store version is pinned to 1.13.4 to be compatible with the most commonly used versions of Tanzu Gemfire for VMs. - version: 1.13.4 + # The Geode Store version is pinned to 1.12.4 to be compatible with the most commonly used versions of Tanzu Gemfire for VMs. + version: 1.12.4 repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 858622ad0235bcc61fb98d7fa48b505eade3fb4a Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 3 Jan 2022 15:42:36 -0500 Subject: [PATCH 668/812] Add Luna API shared library to library path for Java 9+ With Java 9, the extension directory functionality was dropped. This means the buildpack has to handle installation different for Java 8 and Java 9+. With Java 8, we add the required files to the extension directory. With Java 9, we add the required JAR file to the classpath, but this was not sufficient to load the required shared library. To fix this, we are adding the Luna API shared library to the LD_LIBRARY_PATH environment variable. The JVM uses this to locate shared libraries, so it can now find the shared library. Signed-off-by: Daniel Mikusa --- .../framework/luna_security_provider.rb | 8 ++++++++ .../framework/luna_security_provider_spec.rb | 12 +++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/framework/luna_security_provider.rb b/lib/java_buildpack/framework/luna_security_provider.rb index 8b3f15aba9..3a41d30a5d 100644 --- a/lib/java_buildpack/framework/luna_security_provider.rb +++ b/lib/java_buildpack/framework/luna_security_provider.rb @@ -62,6 +62,10 @@ def release if @droplet.java_home.java_9_or_later? @droplet.root_libraries << luna_provider_jar + + @droplet.environment_variables.add_environment_variable( + 'LD_LIBRARY_PATH', "$LD_LIBRARY_PATH:#{ld_lib_path}" + ) else @droplet.extension_directories << ext_dir end @@ -128,6 +132,10 @@ def lib_cklog @droplet.sandbox + 'libs/64/libcklog2.so' end + def ld_lib_path + qualify_path(@droplet.sandbox, @droplet.root) + '/jsp/64/' + end + def setup_ext_dir FileUtils.mkdir ext_dir [luna_provider_jar, luna_api_so].each do |file| diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index d6458de672..6a1810c88a 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -219,7 +219,7 @@ delegate end - it 'adds JAR to classpath during compile in Java 9', + it 'adds JAR to classpath during compile in Java 9+', cache_fixture: 'stub-luna-security-provider.tar' do component.compile @@ -227,18 +227,24 @@ expect(root_libraries).to include(droplet.sandbox + 'jsp/LunaProvider.jar') end - it 'adds JAR to classpath during release in Java 9' do + it 'adds JAR to classpath during release in Java 9+' do component.release expect(root_libraries).to include(droplet.sandbox + 'jsp/LunaProvider.jar') end - it 'adds does not add extension directory in Java 9' do + it 'adds does not add extension directory in Java 9+' do component.release expect(extension_directories).not_to include(droplet.sandbox + 'ext') end + it 'updates environment variables for Java 9+' do + component.release + expect(environment_variables).to include( + 'LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/.java-buildpack/luna_security_provider/jsp/64/' + ) + end end context do From 507158c5c616fd1584981098c0eb73c26edb4465 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Tue, 4 Jan 2022 08:30:43 -0500 Subject: [PATCH 669/812] Update spec/java_buildpack/framework/luna_security_provider_spec.rb Co-authored-by: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> --- spec/java_buildpack/framework/luna_security_provider_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/java_buildpack/framework/luna_security_provider_spec.rb b/spec/java_buildpack/framework/luna_security_provider_spec.rb index 6a1810c88a..b38b7e7333 100644 --- a/spec/java_buildpack/framework/luna_security_provider_spec.rb +++ b/spec/java_buildpack/framework/luna_security_provider_spec.rb @@ -233,7 +233,7 @@ expect(root_libraries).to include(droplet.sandbox + 'jsp/LunaProvider.jar') end - it 'adds does not add extension directory in Java 9+' do + it 'does not add extension directory in Java 9+' do component.release expect(extension_directories).not_to include(droplet.sandbox + 'ext') From 548c8fbb99aae1b67f83dbd775c34162a2d6539e Mon Sep 17 00:00:00 2001 From: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> Date: Thu, 6 Jan 2022 15:25:16 +0000 Subject: [PATCH 670/812] Bump Skywalking agent to use latest available version (#927) Fixed path location of Java Agent in the downloaded tar --- config/sky_walking_agent.yml | 2 +- .../framework/sky_walking_agent.rb | 2 +- spec/fixtures/stub-skywalking-agent.tar.gz | Bin 191 -> 529 bytes .../framework/sky_walking_agent_spec.rb | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/sky_walking_agent.yml b/config/sky_walking_agent.yml index 7ca9923f7d..04048bd6d1 100644 --- a/config/sky_walking_agent.yml +++ b/config/sky_walking_agent.yml @@ -15,6 +15,6 @@ # Configuration for the Sky Walking framework. --- -version: 6.+ +version: + repository_root: https://java-buildpack.cloudfoundry.org/sky-walking default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") diff --git a/lib/java_buildpack/framework/sky_walking_agent.rb b/lib/java_buildpack/framework/sky_walking_agent.rb index 8e0ba3bef1..4a9267661b 100644 --- a/lib/java_buildpack/framework/sky_walking_agent.rb +++ b/lib/java_buildpack/framework/sky_walking_agent.rb @@ -35,7 +35,7 @@ def compile def release credentials = @application.services.find_service(FILTER, 'servers')['credentials'] java_opts = @droplet.java_opts - java_opts.add_javaagent(@droplet.sandbox + 'agent/skywalking-agent.jar') + java_opts.add_javaagent(@droplet.sandbox + 'skywalking-agent.jar') application_name java_opts, credentials sample_n_per_3_secs java_opts, credentials diff --git a/spec/fixtures/stub-skywalking-agent.tar.gz b/spec/fixtures/stub-skywalking-agent.tar.gz index d45c0894460775024b35c1c3a373f9a7cf15076e..8f9eb201d796b16b5fd98f91c19d531980dcda0c 100644 GIT binary patch literal 529 zcmV+s0`C1EiwFqL($--B19NnBVl8uPd3RxKYiVw0En#P6ZgehmVR8WNnoUo_Fc^T_ zi4pa}$$0F=qu6%siU*Tv(0DN#;ouDynFjGA0aU#0r@Pr#gUmsU<3o9$qS8I)0@39l+RYrV2Jf*VRUzp+cH{5jz z<9StJ6bs(|WO-wSIE0)8SM0RLE*OxUBdc+caX5-Y^0}WR_=w?`va;N-*U#aw|B(ur zPg4E=Ea)GHK{M>^;K&KzV?5~wc&(K<-u9-{_k>j-)r56d%{yfd6oFamyMLW z+DK7Zn|1AwNt2%c^Pc_3^?#u_S3~o^=Lv)J|CFEyPfbBcGMyKRHQD+;Y7s&TXD~m= z13?f3L6G@|S{2u4TMYz3=8$B3U|=5{SyTAl0T%|+l)wz^gClDS@f>ggTm+ZE4D5p= zYZ$aBEIufdOkssWVHH9d*#FTbBgn$AWK~M$|3i|w{znkxA43b(TJ?Z@E(p>Q;&3@| z9Fgpo0LT7VxH*uPfqigfjV}TSf*{i-wf{GKqI?^4ep$xY{r}|uU#?Wz<%XMN|6g!} T`+o?6AQR;cOfn&(04x9iN;nC& literal 191 zcmb2|=3tn7R40~!`R!##z9s{K*2KO`+$(Zt9;(b@S|K3TWO(nMTL(9f1n&%i|M|wA zw~zY7-=4C4_4-rEu{kvpufElrHUFAbsh@4urO@1^t8G)0(vy_KdO~k?Og0J1YmAGF znRRWxv-a=i^_x12A4bgcfAhWA=Czl};XmRPtn;707b<-6pIiAS|Mcz43q0?0eV^E| p=k)!q?$TA4C+s)v Date: Thu, 20 Jan 2022 13:07:38 -0500 Subject: [PATCH 671/812] Bump release notes links for Java & Yourkit (#930) Signed-off-by: Daniel Mikusa --- rakelib/versions_task.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index da308f579e..739f289a0f 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -133,12 +133,12 @@ def initialize 'jprofiler_profiler' => { 'cve' => '', 'release' => '[ChangeLog](https://www.ej-technologies.com/download/jprofiler/changelog.html)' }, - 'jre' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2021.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u312/)' }, - 'jre-11' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2021.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.13/)' }, - 'jre-17' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2021.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.1/)' }, + 'jre' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u322/)' }, + 'jre-11' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.14/)' }, + 'jre-17' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.2/)' }, 'jrebel_agent' => { 'cve' => '', 'release' => '[ChangeLog](https://www.jrebel.com/products/jrebel/changelog)' }, 'jvmkill_agent' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, 'lifecycle_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, @@ -170,7 +170,7 @@ def initialize 'tomcat' => { 'cve' => '[Security](https://tomcat.apache.org/security-9.html)', 'release' => '[ChangeLog](https://tomcat.apache.org/tomcat-9.0-doc/changelog.html)' }, 'your_kit_profiler' => { 'cve' => '', - 'release' => '[Release Notes](https://www.yourkit.com/download/yjp_2021_3_builds.jsp)' } + 'release' => '[Release Notes](https://www.yourkit.com/download/yjp_2021_11_builds.jsp)' } }.freeze PLATFORM_PATTERN = /\{platform\}/.freeze From 470cbd4d4a48f7fc2c282096800ef3412bbc7c95 Mon Sep 17 00:00:00 2001 From: BenjaminPerryRoss Date: Wed, 9 Mar 2022 11:08:10 -0800 Subject: [PATCH 672/812] Updated default geode-store to 1.12.5 (#934) --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index f20f1411ef..ce26c5b94d 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -42,5 +42,5 @@ redis_store: geode_store: # The version of Geode Store must be less than or equal to your Tanzu Gemfire for VMs version to ensure compatibility. # The Geode Store version is pinned to 1.12.4 to be compatible with the most commonly used versions of Tanzu Gemfire for VMs. - version: 1.12.4 + version: 1.12.5 repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 70821ba3d1543338290a4b7ccc0b607e96d727a5 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 21 Apr 2022 09:04:52 -0400 Subject: [PATCH 673/812] Update release note links (#937) Signed-off-by: Daniel Mikusa --- rakelib/versions_task.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 739f289a0f..0906a116d1 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -133,12 +133,12 @@ def initialize 'jprofiler_profiler' => { 'cve' => '', 'release' => '[ChangeLog](https://www.ej-technologies.com/download/jprofiler/changelog.html)' }, - 'jre' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u322/)' }, - 'jre-11' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.14/)' }, - 'jre-17' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.2/)' }, + 'jre' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u332/)' }, + 'jre-11' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.15/)' }, + 'jre-17' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.3/)' }, 'jrebel_agent' => { 'cve' => '', 'release' => '[ChangeLog](https://www.jrebel.com/products/jrebel/changelog)' }, 'jvmkill_agent' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, 'lifecycle_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, @@ -170,7 +170,7 @@ def initialize 'tomcat' => { 'cve' => '[Security](https://tomcat.apache.org/security-9.html)', 'release' => '[ChangeLog](https://tomcat.apache.org/tomcat-9.0-doc/changelog.html)' }, 'your_kit_profiler' => { 'cve' => '', - 'release' => '[Release Notes](https://www.yourkit.com/download/yjp_2021_11_builds.jsp)' } + 'release' => '[Release Notes](https://www.yourkit.com/download/yjp_2022_3_builds.jsp)' } }.freeze PLATFORM_PATTERN = /\{platform\}/.freeze From 8afe3bed86eeba69952e6d69327043f93ddf156d Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Fri, 29 Apr 2022 08:22:03 -0400 Subject: [PATCH 674/812] Bump ruby version & versions in CI (#939) Signed-off-by: Daniel Mikusa --- .ruby-version | 2 +- ci/Dockerfile | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.ruby-version b/.ruby-version index ecd7ee50cb..30f69e8cc5 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.8 +2.5.9 diff --git a/ci/Dockerfile b/ci/Dockerfile index 98f6e18b6e..7f81843607 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -33,10 +33,10 @@ RUN eval "$(rbenv init -)" \ && echo 'bundler' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ - && rbenv install 2.5.8 + && rbenv install 2.5.9 RUN eval "$(rbenv init -)" \ - && rbenv install 2.6.6 + && rbenv install 2.7.6 RUN eval "$(rbenv init -)" \ - && rbenv install 2.7.1 + && rbenv install 3.0.4 From 80d599d80c3c288a950aa1743ad1f6503b48e398 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Fri, 29 Apr 2022 09:38:38 -0400 Subject: [PATCH 675/812] Removes Concourse task files (#940) Task files have been moved into the pipeline. Signed-off-by: Daniel Mikusa --- ci/auto-merge.yml | 37 ------------------------------------- ci/builder.yml | 22 ---------------------- ci/package-test.yml | 32 -------------------------------- ci/unit-test.yml | 35 ----------------------------------- ci/versions-json.yml | 32 -------------------------------- ci/versions-markdown.yml | 32 -------------------------------- ci/versions-yaml.yml | 32 -------------------------------- ci/versions.yml | 32 -------------------------------- 8 files changed, 254 deletions(-) delete mode 100644 ci/auto-merge.yml delete mode 100644 ci/builder.yml delete mode 100644 ci/package-test.yml delete mode 100644 ci/unit-test.yml delete mode 100644 ci/versions-json.yml delete mode 100644 ci/versions-markdown.yml delete mode 100644 ci/versions-yaml.yml delete mode 100644 ci/versions.yml diff --git a/ci/auto-merge.yml b/ci/auto-merge.yml deleted file mode 100644 index cb2af56905..0000000000 --- a/ci/auto-merge.yml +++ /dev/null @@ -1,37 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. ---- -platform: linux - -image_resource: - type: registry-image - source: - repository: cfje/java-buildpack - username: ((docker-username)) - password: ((docker-password)) - -inputs: -- name: downstream -- name: upstream - -outputs: -- name: merged - -run: - path: upstream/ci/auto-merge.sh - -params: - GIT_USER_EMAIL: - GIT_USER_NAME: diff --git a/ci/builder.yml b/ci/builder.yml deleted file mode 100644 index 3f637a2ffa..0000000000 --- a/ci/builder.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -platform: linux - -image_resource: - type: registry-image - source: - repository: concourse/builder - -inputs: -- name: builder - -outputs: -- name: image - -caches: -- path: cache - -run: - path: build - -params: - CONTEXT: builder/ci diff --git a/ci/package-test.yml b/ci/package-test.yml deleted file mode 100644 index 2c4cf3cdc9..0000000000 --- a/ci/package-test.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. ---- -platform: linux - -image_resource: - type: registry-image - source: - repository: cfje/java-buildpack - username: ((docker-username)) - password: ((docker-password)) - -inputs: -- name: java-buildpack - -caches: -- path: gems - -run: - path: java-buildpack/ci/package-test.sh diff --git a/ci/unit-test.yml b/ci/unit-test.yml deleted file mode 100644 index 21e547d0ff..0000000000 --- a/ci/unit-test.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. ---- -platform: linux - -image_resource: - type: registry-image - source: - repository: cfje/java-buildpack - username: ((docker-username)) - password: ((docker-password)) - -inputs: -- name: java-buildpack - -caches: -- path: gems - -run: - path: java-buildpack/ci/unit-test.sh - -params: - RBENV_VERSION: diff --git a/ci/versions-json.yml b/ci/versions-json.yml deleted file mode 100644 index 8c35e603e4..0000000000 --- a/ci/versions-json.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. ---- -platform: linux - -image_resource: - type: registry-image - source: - repository: cfje/java-buildpack - username: ((docker-username)) - password: ((docker-password)) - -inputs: -- name: java-buildpack - -caches: -- path: gems - -run: - path: java-buildpack/ci/versions-json.sh diff --git a/ci/versions-markdown.yml b/ci/versions-markdown.yml deleted file mode 100644 index bb43e2e0be..0000000000 --- a/ci/versions-markdown.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. ---- -platform: linux - -image_resource: - type: registry-image - source: - repository: cfje/java-buildpack - username: ((docker-username)) - password: ((docker-password)) - -inputs: -- name: java-buildpack - -caches: -- path: gems - -run: - path: java-buildpack/ci/versions-markdown.sh diff --git a/ci/versions-yaml.yml b/ci/versions-yaml.yml deleted file mode 100644 index 9ee7273d58..0000000000 --- a/ci/versions-yaml.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. ---- -platform: linux - -image_resource: - type: registry-image - source: - repository: cfje/java-buildpack - username: ((docker-username)) - password: ((docker-password)) - -inputs: -- name: java-buildpack - -caches: -- path: gems - -run: - path: java-buildpack/ci/versions-yaml.sh diff --git a/ci/versions.yml b/ci/versions.yml deleted file mode 100644 index d150ba46b2..0000000000 --- a/ci/versions.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. ---- -platform: linux - -image_resource: - type: registry-image - source: - repository: cfje/java-buildpack - username: ((docker-username)) - password: ((docker-password)) - -inputs: -- name: java-buildpack - -caches: -- path: gems - -run: - path: java-buildpack/ci/versions.sh From fd939cf318f53682f78fa1abe71857f43a208bad Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Fri, 6 May 2022 16:55:30 -0400 Subject: [PATCH 676/812] Fixes rubocop violations (#941) - Disable empty blocks under spec tests - Disable string concat style check - Change lint name to MissingSuper - Change `ENV[..]` usage to `ENV.fetch(..., nil)` - Set max for RSpec/MultipleMemoizedHelpers to 10, some tests have a lot of `let(..)` blocks - Set RSpec/VerifiedDoubleReference to enforce string style - Consistently use Naming/VariableNumber, some outliers were snake_case and switched to normalcase - Disable Lint/UselessMethodDefinition in a few specs where it's necessary - Remove some unnecessary whitespace, char groups and escaping in regex blocks - Use `be_nil` instead of `be nil` - Disable Style/GlobalStdStream checks for spec helper - Reduce complexity of versions_tasks and validate - Disable helper limit MultipleMemoizedHelpers for droplet helper - Make the order explicit in a few places by adding parends - Switch from ifelse to case - Use File.write - Remove empty blocks - Fixes all string alignment issues - Fixes all string too long issues - Ignore Ruby 2.6 lints about array slicing since we still need to support Ruby 2.5 - Use an explicit kwargs to be compatible with deprecations and removal in Ruby 2.7 and 3.0 - Bump RubyMine tests to reflect supported version 2.5, 2.7 and 3.0 - Include missing require in filtering_filename_spec.rb that caused it to fail in RubyMine - Freeze const made from dynamics - Adjust kwarg expansion so it's compliant for Ruby 3.0 (this requires some version specific behavior in the spec tests) Signed-off-by: Daniel Mikusa --- .idea/runConfigurations/All_Tests__2_5_.xml | 9 +- .idea/runConfigurations/All_Tests__2_7_.xml | 9 +- ...ll_Tests__2_6_.xml => All_Tests__3_0_.xml} | 11 +- .../Without_Integration_Tests__2_5_.xml | 9 +- .../Without_Integration_Tests__2_7_.xml | 9 +- ...ml => Without_Integration_Tests__3_0_.xml} | 11 +- .rubocop.yml | 20 +- Gemfile.lock | 80 +- java-buildpack.iml | 686 ++++++++++-------- lib/java_buildpack/buildpack.rb | 2 +- lib/java_buildpack/buildpack_version.rb | 4 +- .../component/mutable_java_home.rb | 14 +- lib/java_buildpack/container/dist_zip_like.rb | 2 +- lib/java_buildpack/container/java_main.rb | 2 +- .../container/tomcat/tomcat_geode_store.rb | 8 +- .../container/tomcat/tomcat_instance.rb | 6 +- .../framework/app_dynamics_agent.rb | 4 +- .../framework/aspectj_weaver_agent.rb | 2 +- .../framework/checkmarx_iast_agent.rb | 4 +- .../framework/datadog_javaagent.rb | 2 +- .../framework/elastic_apm_agent.rb | 2 +- .../framework/java_memory_assistant/agent.rb | 2 +- lib/java_buildpack/framework/java_opts.rb | 2 +- .../framework/multi_buildpack.rb | 2 +- .../framework/sky_walking_agent.rb | 2 +- lib/java_buildpack/jre/ibm_jre_initializer.rb | 8 +- lib/java_buildpack/jre/open_jdk_like_jre.rb | 3 +- .../jre/open_jdk_like_memory_calculator.rb | 4 +- .../jre/open_jdk_like_security_providers.rb | 2 +- lib/java_buildpack/logging/logger_factory.rb | 2 +- .../repository/version_resolver.rb | 10 +- .../util/cache/download_cache.rb | 8 +- .../util/configuration_utils.rb | 7 +- lib/java_buildpack/util/external_config.rb | 2 +- lib/java_buildpack/util/filtering_pathname.rb | 4 +- lib/java_buildpack/util/groovy_utils.rb | 4 +- lib/java_buildpack/util/java_main_utils.rb | 2 +- lib/java_buildpack/util/play/post22.rb | 2 +- lib/java_buildpack/util/play/pre22_dist.rb | 2 +- lib/java_buildpack/util/properties.rb | 6 +- lib/java_buildpack/util/spring_boot_utils.rb | 2 +- lib/java_buildpack/util/tokenized_version.rb | 24 +- rakelib/dependency_cache_task.rb | 4 +- rakelib/package.rb | 4 +- rakelib/stage_buildpack_task.rb | 4 +- rakelib/versions_task.rb | 48 +- spec/console_helper.rb | 2 + spec/droplet_helper.rb | 6 +- spec/java_buildpack/buildpack_spec.rb | 2 + .../component/additional_libraries_spec.rb | 4 +- .../component/base_component_spec.rb | 2 +- .../component/extension_directories_spec.rb | 4 +- .../component/immutable_java_home_spec.rb | 2 +- .../component/modular_component_spec.rb | 2 + .../component/security_providers_spec.rb | 2 +- .../container/dist_zip_like_spec.rb | 4 +- .../container/java_main_spec.rb | 44 +- .../tomcat/tomcat_geode_store_spec.rb | 10 +- .../container/tomcat/tomcat_instance_spec.rb | 2 +- spec/java_buildpack/container/tomcat_spec.rb | 2 +- .../framework/app_dynamics_agent_spec.rb | 2 +- .../framework/contrast_security_agent_spec.rb | 2 +- .../framework/datadog_javaagent_spec.rb | 8 +- .../framework/dynatrace_one_agent_spec.rb | 14 +- .../framework/introscope_agent_spec.rb | 22 +- .../java_memory_assistant/agent_spec.rb | 12 +- .../java_memory_assistant/clean_up_spec.rb | 6 +- .../heap_dump_folder_spec.rb | 4 +- .../framework/java_opts_spec.rb | 4 +- .../framework/java_security_spec.rb | 2 +- .../framework/jprofiler_profiler_spec.rb | 6 +- .../framework/multi_buildpack_spec.rb | 8 +- .../riverbed_appinternals_agent_spec.rb | 4 +- .../framework/sky_walking_agent_spec.rb | 2 +- .../framework/your_kit_profiler_spec.rb | 19 +- spec/java_buildpack/jre/ibm_jre_spec.rb | 2 + .../open_jdk_like_memory_calculator_spec.rb | 18 +- spec/java_buildpack/jre/open_jdk_like_spec.rb | 11 +- .../util/cache/download_cache_spec.rb | 26 +- .../util/configuration_utils_spec.rb | 4 +- spec/java_buildpack/util/constantize_spec.rb | 2 + .../util/filtering_pathname_spec.rb | 9 +- spec/java_buildpack/util/play/post22_spec.rb | 10 +- .../util/play/pre22_dist_spec.rb | 8 +- .../util/spring_boot_utils_spec.rb | 4 +- spec/logging_helper.rb | 4 +- spec/memory_limit_helper.rb | 2 +- 87 files changed, 785 insertions(+), 574 deletions(-) rename .idea/runConfigurations/{All_Tests__2_6_.xml => All_Tests__3_0_.xml} (85%) rename .idea/runConfigurations/{Without_Integration_Tests__2_6_.xml => Without_Integration_Tests__3_0_.xml} (85%) diff --git a/.idea/runConfigurations/All_Tests__2_5_.xml b/.idea/runConfigurations/All_Tests__2_5_.xml index 46e189f459..e2694fee68 100644 --- a/.idea/runConfigurations/All_Tests__2_5_.xml +++ b/.idea/runConfigurations/All_Tests__2_5_.xml @@ -2,10 +2,10 @@ - - + + - + @@ -19,8 +19,9 @@ - + + diff --git a/.idea/runConfigurations/All_Tests__2_7_.xml b/.idea/runConfigurations/All_Tests__2_7_.xml index 904b0c4819..4f9031d53b 100644 --- a/.idea/runConfigurations/All_Tests__2_7_.xml +++ b/.idea/runConfigurations/All_Tests__2_7_.xml @@ -2,10 +2,10 @@ - - + + - + @@ -19,8 +19,9 @@ - + + diff --git a/.idea/runConfigurations/All_Tests__2_6_.xml b/.idea/runConfigurations/All_Tests__3_0_.xml similarity index 85% rename from .idea/runConfigurations/All_Tests__2_6_.xml rename to .idea/runConfigurations/All_Tests__3_0_.xml index 14647856f7..6dd0b62d5b 100644 --- a/.idea/runConfigurations/All_Tests__2_6_.xml +++ b/.idea/runConfigurations/All_Tests__3_0_.xml @@ -1,11 +1,11 @@ - + - - + + - + @@ -19,8 +19,9 @@ - + + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml index f232d1f8e0..bd9dbbf1f5 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml @@ -2,10 +2,10 @@ - - + + - + @@ -19,8 +19,9 @@ - + + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_7_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_7_.xml index 132d4472d6..6432e7e234 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_7_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_7_.xml @@ -2,10 +2,10 @@ - - + + - + @@ -19,8 +19,9 @@ - + + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml b/.idea/runConfigurations/Without_Integration_Tests__3_0_.xml similarity index 85% rename from .idea/runConfigurations/Without_Integration_Tests__2_6_.xml rename to .idea/runConfigurations/Without_Integration_Tests__3_0_.xml index abaaac0c98..33a62d88ac 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_6_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__3_0_.xml @@ -1,11 +1,11 @@ - + - - + + - + @@ -19,8 +19,9 @@ - + + diff --git a/.rubocop.yml b/.rubocop.yml index b48540327c..b9ffa2b3fe 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,6 +3,7 @@ require: rubocop-rspec AllCops: NewCops: enable + SuggestExtensions: false Exclude: - 'build/**/*' Layout/EmptyLinesAroundBlockBody: @@ -17,7 +18,7 @@ Layout/LineLength: Layout/MultilineOperationIndentation: Enabled: false Metrics/AbcSize: - Max: 25 + Max: 25 Metrics/BlockLength: Exclude: - 'spec/**/*.rb' @@ -53,5 +54,20 @@ Style/Documentation: Enabled: false Style/FormatStringToken: Enabled: false -Style/MethodMissingSuper: +Lint/MissingSuper: + Enabled: false +Style/StringConcatenation: + Enabled: false +Lint/EmptyBlock: + Exclude: + - 'spec/**/*.rb' +RSpec/MultipleMemoizedHelpers: + Max: 10 +RSpec/VerifiedDoubleReference: + EnforcedStyle: string +Style/OptionalBooleanParameter: Enabled: false +Lint/RedundantCopDisableDirective: + Enabled: false # disabled as this can be tough to manage across multiple ruby versions +Style/RedundantFreeze: + Enabled: false # enable when we only support ruby 3.0+ diff --git a/Gemfile.lock b/Gemfile.lock index e980a3aa17..b3eb261a97 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,55 +3,59 @@ GEM specs: addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) - ast (2.4.0) - crack (0.4.3) - safe_yaml (~> 1.0.0) - diff-lcs (1.3) + ast (2.4.2) + crack (0.4.5) + rexml + diff-lcs (1.5.0) hashdiff (1.0.1) - jaro_winkler (1.5.4) - parallel (1.19.1) - parser (2.7.1.1) - ast (~> 2.4.0) - public_suffix (4.0.6) - rainbow (3.0.0) - rake (13.0.1) + parallel (1.22.1) + parser (3.1.2.0) + ast (~> 2.4.1) + public_suffix (4.0.7) + rainbow (3.1.1) + rake (13.0.6) redcarpet (3.5.1) + regexp_parser (2.3.1) rexml (3.2.5) - rspec (3.9.0) - rspec-core (~> 3.9.0) - rspec-expectations (~> 3.9.0) - rspec-mocks (~> 3.9.0) - rspec-core (3.9.1) - rspec-support (~> 3.9.1) - rspec-expectations (3.9.1) + rspec (3.11.0) + rspec-core (~> 3.11.0) + rspec-expectations (~> 3.11.0) + rspec-mocks (~> 3.11.0) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-mocks (3.9.1) + rspec-support (~> 3.11.0) + rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-support (3.9.2) - rubocop (0.82.0) - jaro_winkler (~> 1.5.1) + rspec-support (~> 3.11.0) + rspec-support (3.11.0) + rubocop (1.28.2) parallel (~> 1.10) - parser (>= 2.7.0.1) + parser (>= 3.1.0.0) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) rexml + rubocop-ast (>= 1.17.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 2.0) - rubocop-rspec (1.38.1) - rubocop (>= 0.68.1) - ruby-progressbar (1.10.1) - rubyzip (2.3.0) - safe_yaml (1.0.5) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.17.0) + parser (>= 3.1.1.0) + rubocop-rspec (2.10.0) + rubocop (~> 1.19) + ruby-progressbar (1.11.0) + rubyzip (2.3.2) tee (1.0.0) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - unicode-display_width (1.7.0) - webmock (3.8.3) - addressable (>= 2.3.6) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.1.0) + webmock (3.14.0) + addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - yard (0.9.24) + webrick (1.7.0) + yard (0.9.27) + webrick (~> 1.7.0) PLATFORMS ruby @@ -69,4 +73,4 @@ DEPENDENCIES yard BUNDLED WITH - 2.2.16 + 2.3.12 diff --git a/java-buildpack.iml b/java-buildpack.iml index 0135aaf5b0..c156f343b4 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -1,259 +1,378 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -265,37 +384,38 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/java_buildpack/buildpack.rb b/lib/java_buildpack/buildpack.rb index 69827e4129..66c7154944 100644 --- a/lib/java_buildpack/buildpack.rb +++ b/lib/java_buildpack/buildpack.rb @@ -116,7 +116,7 @@ def release private - BUILDPACK_MESSAGE = "#{'----->'.red.bold} #{'Java Buildpack'.blue.bold} %s" + BUILDPACK_MESSAGE = "#{'----->'.red.bold} #{'Java Buildpack'.blue.bold} %s".freeze LOAD_ROOT = (Pathname.new(__FILE__).dirname + '..').freeze diff --git a/lib/java_buildpack/buildpack_version.rb b/lib/java_buildpack/buildpack_version.rb index f406a6014c..0bf17b6c25 100644 --- a/lib/java_buildpack/buildpack_version.rb +++ b/lib/java_buildpack/buildpack_version.rb @@ -49,9 +49,9 @@ class BuildpackVersion def initialize(should_log = true) configuration = JavaBuildpack::Util::ConfigurationUtils.load('version', true, should_log) @hash = configuration['hash'] || calculate_hash - @offline = configuration['offline'] || ENV['OFFLINE'].to_b + @offline = configuration['offline'] || ENV.fetch('OFFLINE', nil).to_b @remote = configuration['remote'] || calculate_remote - @version = configuration['version'] || ENV['VERSION'] || @hash + @version = configuration['version'] || ENV.fetch('VERSION', nil) || @hash return unless should_log diff --git a/lib/java_buildpack/component/mutable_java_home.rb b/lib/java_buildpack/component/mutable_java_home.rb index 48b7a4bd92..ddd4c0993f 100644 --- a/lib/java_buildpack/component/mutable_java_home.rb +++ b/lib/java_buildpack/component/mutable_java_home.rb @@ -38,28 +38,28 @@ class MutableJavaHome # Whether or not the version of Java is 8 or later # @return [Boolean] +true+ if and only if the version is 1.8.0 or later def java_8_or_later? - @version >= VERSION_8 + @version >= VERSION8 end # Whether or not the version of Java is 9 or later # @return [Boolean] +true+ if and only if the version is 9.0.0 or later def java_9_or_later? - @version >= VERSION_9 + @version >= VERSION9 end # Whether or not the version of Java is 10 or later # @return [Boolean] +true+ if and only if the version is 10.0.0 or later def java_10_or_later? - @version >= VERSION_10 + @version >= VERSION10 end - VERSION_8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0').freeze + VERSION8 = JavaBuildpack::Util::TokenizedVersion.new('1.8.0').freeze - VERSION_9 = JavaBuildpack::Util::TokenizedVersion.new('9.0.0').freeze + VERSION9 = JavaBuildpack::Util::TokenizedVersion.new('9.0.0').freeze - VERSION_10 = JavaBuildpack::Util::TokenizedVersion.new('10.0.0').freeze + VERSION10 = JavaBuildpack::Util::TokenizedVersion.new('10.0.0').freeze - private_constant :VERSION_8, :VERSION_9, :VERSION_10 + private_constant :VERSION8, :VERSION9, :VERSION10 end diff --git a/lib/java_buildpack/container/dist_zip_like.rb b/lib/java_buildpack/container/dist_zip_like.rb index 14f0717363..208d395f06 100644 --- a/lib/java_buildpack/container/dist_zip_like.rb +++ b/lib/java_buildpack/container/dist_zip_like.rb @@ -79,7 +79,7 @@ def supports? ARGUMENTS_PROPERTY = 'arguments' - PATTERN_APP_CLASSPATH = /^declare -r app_classpath=\"(.*)\"$/.freeze + PATTERN_APP_CLASSPATH = /^declare -r app_classpath="(.*)"$/.freeze PATTERN_CLASSPATH = /^CLASSPATH=(.*)$/.freeze diff --git a/lib/java_buildpack/container/java_main.rb b/lib/java_buildpack/container/java_main.rb index 9a1896f9bc..dc00ee1fab 100644 --- a/lib/java_buildpack/container/java_main.rb +++ b/lib/java_buildpack/container/java_main.rb @@ -112,7 +112,7 @@ def main_class def manifest_class_path values = JavaBuildpack::Util::JavaMainUtils.manifest(@application)[CLASS_PATH_PROPERTY] - values.nil? ? [] : values.split(' ').map { |value| @droplet.root + value } + values.nil? ? [] : values.split.map { |value| @droplet.root + value } end def thin_root diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 9b6d410611..6fda2f971d 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -142,7 +142,7 @@ def detect_geode_tomcat_version if geode_modules_tomcat_pattern.match(file) unless geode_tomcat_version.nil? raise('Multiple versions of geode-modules-tomcat jar found. ' \ - 'Please verify your geode_store tar only contains one geode-modules-tomcat jar.') + 'Please verify your geode_store tar only contains one geode-modules-tomcat jar.') end geode_tomcat_version = geode_modules_tomcat_pattern.match(file).named_captures['version'] @@ -151,7 +151,7 @@ def detect_geode_tomcat_version if geode_tomcat_version.nil? raise('Geode Tomcat module not found. ' \ - 'Please verify your geode_store tar contains a geode-modules-tomcat jar.') + 'Please verify your geode_store tar contains a geode-modules-tomcat jar.') end puts " Detected Geode Tomcat #{geode_tomcat_version} module" @@ -159,8 +159,8 @@ def detect_geode_tomcat_version # leave possibility for generic jar/session manager class that is compatible with all tomcat versions if !geode_tomcat_version.empty? && geode_tomcat_version != @tomcat_version puts " WARNING: Tomcat version #{@tomcat_version} " \ - "does not match Geode Tomcat #{geode_tomcat_version} module. " \ - 'If you encounter compatibility issues, please make sure these versions match.' + "does not match Geode Tomcat #{geode_tomcat_version} module. " \ + 'If you encounter compatibility issues, please make sure these versions match.' end @session_manager_classname = diff --git a/lib/java_buildpack/container/tomcat/tomcat_instance.rb b/lib/java_buildpack/container/tomcat/tomcat_instance.rb index cd78ae1df4..a046c3533a 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_instance.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_instance.rb @@ -53,13 +53,13 @@ def supports? true end - TOMCAT_8 = JavaBuildpack::Util::TokenizedVersion.new('8.0.0').freeze + TOMCAT8 = JavaBuildpack::Util::TokenizedVersion.new('8.0.0').freeze - private_constant :TOMCAT_8 + private_constant :TOMCAT8 # Checks whether Tomcat instance is Tomcat 7 compatible def tomcat_7_compatible - @version < TOMCAT_8 + @version < TOMCAT8 end private diff --git a/lib/java_buildpack/framework/app_dynamics_agent.rb b/lib/java_buildpack/framework/app_dynamics_agent.rb index f9d41c0198..9cd9778380 100644 --- a/lib/java_buildpack/framework/app_dynamics_agent.rb +++ b/lib/java_buildpack/framework/app_dynamics_agent.rb @@ -81,7 +81,7 @@ def supports? private - FILTER = /app[-]?dynamics/.freeze + FILTER = /app-?dynamics/.freeze private_constant :FILTER @@ -182,7 +182,7 @@ def save_cfg_file(file, conf_file) end def escape(value) - if /\$[\(\{][^\)\}]+[\)\}]/ =~ value + if /\$[({][^)}]+[)}]/ =~ value "\\\"#{value}\\\"" else Shellwords.escape(value) diff --git a/lib/java_buildpack/framework/aspectj_weaver_agent.rb b/lib/java_buildpack/framework/aspectj_weaver_agent.rb index e49ae0d688..11a4641453 100644 --- a/lib/java_buildpack/framework/aspectj_weaver_agent.rb +++ b/lib/java_buildpack/framework/aspectj_weaver_agent.rb @@ -33,7 +33,7 @@ class AspectjWeaverAgent < JavaBuildpack::Component::BaseComponent def initialize(context) super(context) - @jar_finder = JavaBuildpack::Util::JarFinder.new(/.*aspectjweaver-([\d].*)\.jar/) + @jar_finder = JavaBuildpack::Util::JarFinder.new(/.*aspectjweaver-(\d.*)\.jar/) end # (see JavaBuildpack::Component::BaseComponent#detect) diff --git a/lib/java_buildpack/framework/checkmarx_iast_agent.rb b/lib/java_buildpack/framework/checkmarx_iast_agent.rb index b92e7afa86..219826edd7 100644 --- a/lib/java_buildpack/framework/checkmarx_iast_agent.rb +++ b/lib/java_buildpack/framework/checkmarx_iast_agent.rb @@ -61,9 +61,9 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release # Default cxAppTag to application name if not set as an env var - app_tag = ENV['cxAppTag'] || application_name + app_tag = ENV.fetch('cxAppTag', nil) || application_name # Default team to CxServer if not set as env var - team = ENV['cxTeam'] || 'CxServer' + team = ENV.fetch('cxTeam', nil) || 'CxServer' @droplet.java_opts .add_javaagent(@droplet.sandbox + 'cx-launcher.jar') diff --git a/lib/java_buildpack/framework/datadog_javaagent.rb b/lib/java_buildpack/framework/datadog_javaagent.rb index 24fb07ea38..a2e2d11f33 100644 --- a/lib/java_buildpack/framework/datadog_javaagent.rb +++ b/lib/java_buildpack/framework/datadog_javaagent.rb @@ -83,7 +83,7 @@ def fix_class_count 1.upto(cnt) do |i| File.open("#{zipdir}/#{i}.class", 'w') do |f| - f.write(i.to_s) + File.write(f, i.to_s) end end diff --git a/lib/java_buildpack/framework/elastic_apm_agent.rb b/lib/java_buildpack/framework/elastic_apm_agent.rb index ba613f374a..bba02c8f33 100644 --- a/lib/java_buildpack/framework/elastic_apm_agent.rb +++ b/lib/java_buildpack/framework/elastic_apm_agent.rb @@ -90,7 +90,7 @@ def apply_user_configuration(credentials, configuration) def write_java_opts(java_opts, configuration) configuration.each do |key, value| - if /\$[\(\{][^\)\}]+[\)\}]/ =~ value + if /\$[({][^)}]+[)}]/ =~ value # we need \" because this is a system property which ends up inside `JAVA_OPTS` which is already quoted java_opts.add_system_property("elastic.apm.#{key}", "\\\"#{value}\\\"") else diff --git a/lib/java_buildpack/framework/java_memory_assistant/agent.rb b/lib/java_buildpack/framework/java_memory_assistant/agent.rb index 825d34bb12..50edfc800c 100644 --- a/lib/java_buildpack/framework/java_memory_assistant/agent.rb +++ b/lib/java_buildpack/framework/java_memory_assistant/agent.rb @@ -93,7 +93,7 @@ def add_system_prop_if_config_present(config_entry, system_property_name) end def log_level - @configuration['log_level'] || ENV['JBP_LOG_LEVEL'] || 'ERROR' + @configuration['log_level'] || ENV.fetch('JBP_LOG_LEVEL', nil) || 'ERROR' end def normalized_log_level diff --git a/lib/java_buildpack/framework/java_opts.rb b/lib/java_buildpack/framework/java_opts.rb index 373ca796c7..195c98772a 100644 --- a/lib/java_buildpack/framework/java_opts.rb +++ b/lib/java_buildpack/framework/java_opts.rb @@ -62,7 +62,7 @@ def escape_value(str) return "''" if str.empty? str - .gsub(%r{([^A-Za-z0-9_\-.,:\/@\n$\\])}, '\\\\\\1') + .gsub(%r{([^A-Za-z0-9_\-.,:/@\n$\\])}, '\\\\\\1') .gsub(/\n/, "'\n'") end diff --git a/lib/java_buildpack/framework/multi_buildpack.rb b/lib/java_buildpack/framework/multi_buildpack.rb index 0367e3bc87..1b0500d4a8 100644 --- a/lib/java_buildpack/framework/multi_buildpack.rb +++ b/lib/java_buildpack/framework/multi_buildpack.rb @@ -40,7 +40,7 @@ def initialize(context) # (see JavaBuildpack::Component::BaseComponent#detect) def detect - !dep_directories.empty? ? "multi-buildpack=#{names(dep_directories).join(',')}" : nil + dep_directories.empty? ? nil : "multi-buildpack=#{names(dep_directories).join(',')}" end # (see JavaBuildpack::Component::BaseComponent#compile) diff --git a/lib/java_buildpack/framework/sky_walking_agent.rb b/lib/java_buildpack/framework/sky_walking_agent.rb index 4a9267661b..c914f091f5 100644 --- a/lib/java_buildpack/framework/sky_walking_agent.rb +++ b/lib/java_buildpack/framework/sky_walking_agent.rb @@ -55,7 +55,7 @@ def supports? private - FILTER = /sky[-]?walking/.freeze + FILTER = /sky-?walking/.freeze private_constant :FILTER diff --git a/lib/java_buildpack/jre/ibm_jre_initializer.rb b/lib/java_buildpack/jre/ibm_jre_initializer.rb index 57de71f64f..4bf77a26ab 100644 --- a/lib/java_buildpack/jre/ibm_jre_initializer.rb +++ b/lib/java_buildpack/jre/ibm_jre_initializer.rb @@ -107,7 +107,7 @@ def heap_ratio end def memory_limit_finder - memory_limit = ENV['MEMORY_LIMIT'] + memory_limit = ENV.fetch('MEMORY_LIMIT', nil) return nil unless memory_limit memory_limit_size = memory_size_bytes(memory_limit) @@ -158,9 +158,9 @@ def heap_size_calculator(membytes, heapratio) end def memory_size_minified(membytes) - giga = membytes / 2**(10 * 3) - mega = membytes / 2**(10 * 2) - kilo = (membytes / 2**(10 * 1)).round + giga = membytes / (2**(10 * 3)) + mega = membytes / (2**(10 * 2)) + kilo = (membytes / (2**(10 * 1))).round if check_is_integer?(giga) minified_size_calculator(giga, 'G') elsif check_is_integer?(mega) diff --git a/lib/java_buildpack/jre/open_jdk_like_jre.rb b/lib/java_buildpack/jre/open_jdk_like_jre.rb index eb41fe2562..a0a81a6334 100644 --- a/lib/java_buildpack/jre/open_jdk_like_jre.rb +++ b/lib/java_buildpack/jre/open_jdk_like_jre.rb @@ -25,6 +25,7 @@ module JavaBuildpack module Jre + # rubocop: disable Naming/VariableNumber # Encapsulates the detect, compile, and release functionality for selecting an OpenJDK-like JRE. class OpenJDKLikeJre < JavaBuildpack::Component::VersionedDependencyComponent @@ -91,6 +92,6 @@ def link_local_dns? end end - + # rubocop: enable Naming/VariableNumber end end diff --git a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb index c760538294..7a2fd20d4f 100644 --- a/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb +++ b/lib/java_buildpack/jre/open_jdk_like_memory_calculator.rb @@ -54,8 +54,8 @@ def compile # @return [String] the memory calculation command def memory_calculation_command "CALCULATED_MEMORY=$(#{memory_calculation_string(@droplet.root)}) && " \ - 'echo JVM Memory Configuration: $CALCULATED_MEMORY && ' \ - 'JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"' + 'echo JVM Memory Configuration: $CALCULATED_MEMORY && ' \ + 'JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"' end # (see JavaBuildpack::Component::BaseComponent#release) diff --git a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb index 75b2a443a7..0439f23e28 100644 --- a/lib/java_buildpack/jre/open_jdk_like_security_providers.rb +++ b/lib/java_buildpack/jre/open_jdk_like_security_providers.rb @@ -40,7 +40,7 @@ def compile def release return if @droplet.java_home.java_9_or_later? - @droplet.extension_directories << java_security.parent.parent + 'ext' unless java_security.nil? + @droplet.extension_directories << (java_security.parent.parent + 'ext') unless java_security.nil? end private diff --git a/lib/java_buildpack/logging/logger_factory.rb b/lib/java_buildpack/logging/logger_factory.rb index 4eccbde561..ce1d435b5b 100644 --- a/lib/java_buildpack/logging/logger_factory.rb +++ b/lib/java_buildpack/logging/logger_factory.rb @@ -135,7 +135,7 @@ def ruby_mode end def severity(configuration) - severity = ENV['JBP_LOG_LEVEL'] + severity = ENV.fetch('JBP_LOG_LEVEL', nil) severity ||= ruby_mode severity ||= configuration['default_log_level'] severity ||= 'INFO' diff --git a/lib/java_buildpack/repository/version_resolver.rb b/lib/java_buildpack/repository/version_resolver.rb index 6d9beb1db3..107c22eb1b 100644 --- a/lib/java_buildpack/repository/version_resolver.rb +++ b/lib/java_buildpack/repository/version_resolver.rb @@ -42,11 +42,9 @@ def resolve(candidate_version, versions) tokenized_candidate_version = safe_candidate_version candidate_version tokenized_versions = versions.map { |version| create_token(version) }.compact - version = tokenized_versions - .select { |tokenized_version| matches? tokenized_candidate_version, tokenized_version } - .max { |a, b| a <=> b } - - version + tokenized_versions + .select { |tokenized_version| matches? tokenized_candidate_version, tokenized_version } + .max { |a, b| a <=> b } end private @@ -78,7 +76,7 @@ def safe_candidate_version(candidate_version) def matches?(tokenized_candidate_version, tokenized_version) wildcard_matched = false (0..3).all? do |i| - next true if wildcard_matched || tokenized_candidate_version[i].nil? && tokenized_version[i].nil? + next true if wildcard_matched || (tokenized_candidate_version[i].nil? && tokenized_version[i].nil?) next false if tokenized_candidate_version[i].nil? && !tokenized_version[i].nil? diff --git a/lib/java_buildpack/util/cache/download_cache.rb b/lib/java_buildpack/util/cache/download_cache.rb index 81faffd7df..9da9f33e72 100644 --- a/lib/java_buildpack/util/cache/download_cache.rb +++ b/lib/java_buildpack/util/cache/download_cache.rb @@ -301,7 +301,7 @@ def http_options(rich_uri) end def no_proxy?(uri) - hosts = (ENV['no_proxy'] || ENV['NO_PROXY'] || '').split ',' + hosts = (ENV.fetch('no_proxy', nil) || ENV.fetch('NO_PROXY', nil) || '').split ',' hosts.any? { |host| uri.host.end_with? host } end @@ -309,9 +309,9 @@ def proxy(uri) proxy_uri = if no_proxy?(uri) URI.parse('') elsif secure?(uri) - URI.parse(ENV['https_proxy'] || ENV['HTTPS_PROXY'] || '') + URI.parse(ENV.fetch('https_proxy', nil) || ENV.fetch('HTTPS_PROXY', nil) || '') else - URI.parse(ENV['http_proxy'] || ENV['HTTP_PROXY'] || '') + URI.parse(ENV.fetch('http_proxy', nil) || ENV.fetch('HTTP_PROXY', nil) || '') end proxy_user = proxy_uri.user ? URI.decode_www_form_component(proxy_uri.user) : nil @@ -349,7 +349,7 @@ def secure?(uri) def update(uri, cached_file) http_options = http_options(uri) - proxy(uri).start(uri.host, uri.port, http_options) do |http| + proxy(uri).start(uri.host, uri.port, **http_options) do |http| @logger.debug { "HTTP: #{http.address}, #{http.port}, #{http_options}" } debug_ssl(http) if secure?(uri) diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 2f51398ded..c50ae73be7 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -46,7 +46,7 @@ def load(identifier, clean_nil_values = true, should_log = true) if file.exist? var_name = environment_variable_name(identifier) - user_provided = ENV[var_name] + user_provided = ENV.fetch(var_name, nil) configuration = load_configuration(file, user_provided, var_name, clean_nil_values, should_log) elsif should_log logger.debug { "No configuration file #{file} found" } @@ -131,9 +131,10 @@ def load_configuration(file, user_provided, var_name, clean_nil_values, should_l end def merge_configuration(configuration, user_provided_value, var_name, should_log) - if user_provided_value.is_a?(Hash) + case user_provided_value + when Hash configuration = do_merge(configuration, user_provided_value, should_log) - elsif user_provided_value.is_a?(Array) + when Array user_provided_value.each { |new_prop| configuration = do_merge(configuration, new_prop, should_log) } else raise "User configuration value in environment variable #{var_name} is not valid: #{user_provided_value}" diff --git a/lib/java_buildpack/util/external_config.rb b/lib/java_buildpack/util/external_config.rb index a37bedd47d..2d2dfbe170 100644 --- a/lib/java_buildpack/util/external_config.rb +++ b/lib/java_buildpack/util/external_config.rb @@ -63,7 +63,7 @@ def check_if_resource_exists(resource_uri, conf_file) # check if resource exists on remote server begin opts = { use_ssl: true } if resource_uri.scheme == 'https' - response = Net::HTTP.start(resource_uri.host, resource_uri.port, opts) do |http| + response = Net::HTTP.start(resource_uri.host, resource_uri.port, **opts) do |http| req = Net::HTTP::Head.new(resource_uri) if resource_uri.user != '' || resource_uri.password != '' req.basic_auth(resource_uri.user, resource_uri.password) diff --git a/lib/java_buildpack/util/filtering_pathname.rb b/lib/java_buildpack/util/filtering_pathname.rb index 2a71c80279..133b7987cb 100644 --- a/lib/java_buildpack/util/filtering_pathname.rb +++ b/lib/java_buildpack/util/filtering_pathname.rb @@ -103,9 +103,9 @@ def entries end # @see Pathname. - def open(mode = nil, *args, &block) + def open(mode = nil, *args, **kwargs, &block) check_mutable if mode =~ /[wa]/ - delegate.open(mode, *args, &block) + delegate.open(mode, *args, **kwargs, &block) end # @see Pathname. diff --git a/lib/java_buildpack/util/groovy_utils.rb b/lib/java_buildpack/util/groovy_utils.rb index 98a0ca089e..39e798312e 100644 --- a/lib/java_buildpack/util/groovy_utils.rb +++ b/lib/java_buildpack/util/groovy_utils.rb @@ -33,7 +33,7 @@ class << self # @param [File] file the file to scan # @return [Boolean] +true+ if the file is a +beans+style configuration, +false+ otherwise. def beans?(file) - safe_read(file) { Pathname.new(file).read =~ /beans[\s]*\{/ } + safe_read(file) { Pathname.new(file).read =~ /beans\s*\{/ } end # Indicates whether a file has a +main()+ method in it @@ -49,7 +49,7 @@ def main_method?(file) # @param [File] file the file to scan # @return [Boolean] +true+ if the file is a POGO, +false+ otherwise. def pogo?(file) - safe_read(file) { Pathname.new(file).read =~ /class [\w]+[\s\w]*\{/ } + safe_read(file) { Pathname.new(file).read =~ /class \w+[\s\w]*\{/ } end # Indicates whether a file has a shebang diff --git a/lib/java_buildpack/util/java_main_utils.rb b/lib/java_buildpack/util/java_main_utils.rb index 4dd11c12e8..0ecbfe21f5 100644 --- a/lib/java_buildpack/util/java_main_utils.rb +++ b/lib/java_buildpack/util/java_main_utils.rb @@ -46,7 +46,7 @@ def main_class(application, configuration = nil) # @return [Properties] the properties from the application's manifest (if any) def manifest(application) manifest_file = application.root + 'META-INF/MANIFEST.MF' - manifest_file = manifest_file.exist? ? manifest_file : nil + manifest_file = nil unless manifest_file.exist? JavaBuildpack::Util::Properties.new(manifest_file) end diff --git a/lib/java_buildpack/util/play/post22.rb b/lib/java_buildpack/util/play/post22.rb index 18177af91d..7bb19629bf 100644 --- a/lib/java_buildpack/util/play/post22.rb +++ b/lib/java_buildpack/util/play/post22.rb @@ -35,7 +35,7 @@ def augment_classpath "$app_home/#{additional_library.relative_path_from(start_script.dirname)}" end - update_file start_script, /^declare -r app_classpath=\"(.*)\"$/, + update_file start_script, /^declare -r app_classpath="(.*)"$/, "declare -r app_classpath=\"#{additional_classpath.join(':')}:\\1\"" end diff --git a/lib/java_buildpack/util/play/pre22_dist.rb b/lib/java_buildpack/util/play/pre22_dist.rb index 65bea1dc4c..9503100b4f 100644 --- a/lib/java_buildpack/util/play/pre22_dist.rb +++ b/lib/java_buildpack/util/play/pre22_dist.rb @@ -35,7 +35,7 @@ def augment_classpath "$scriptdir/#{additional_library.relative_path_from(root)}" end - update_file start_script, /^classpath=\"(.*)\"$/, "classpath=\"#{additional_classpath.join(':')}:\\1\"" + update_file start_script, /^classpath="(.*)"$/, "classpath=\"#{additional_classpath.join(':')}:\\1\"" end end diff --git a/lib/java_buildpack/util/properties.rb b/lib/java_buildpack/util/properties.rb index d3315c6544..8efc512d19 100644 --- a/lib/java_buildpack/util/properties.rb +++ b/lib/java_buildpack/util/properties.rb @@ -36,7 +36,7 @@ def initialize(file_name) contents.each_line do |line| next if blank_line?(line) || comment_line?(line) - match_data = /^[\s]*([^:=\s]+)[\s]*[=:]?[\s]*(.*?)\s*$/.match(line) + match_data = /^\s*([^:=\s]+)\s*[=:]?\s*(.*?)\s*$/.match(line) self[match_data[1]] = match_data[2] if match_data end end @@ -44,11 +44,11 @@ def initialize(file_name) private def blank_line?(line) - line =~ /^[\s]*$/ + line =~ /^\s*$/ end def comment_line?(line) - line =~ /^[\s]*[#!].*$/ + line =~ /^\s*[#!].*$/ end end diff --git a/lib/java_buildpack/util/spring_boot_utils.rb b/lib/java_buildpack/util/spring_boot_utils.rb index c6ea5535dc..bdcfe329c2 100644 --- a/lib/java_buildpack/util/spring_boot_utils.rb +++ b/lib/java_buildpack/util/spring_boot_utils.rb @@ -29,7 +29,7 @@ class SpringBootUtils include JavaBuildpack::Util::Shell def initialize - @jar_finder = JavaBuildpack::Util::JarFinder.new(/.*spring-boot-([\d].*)\.jar/) + @jar_finder = JavaBuildpack::Util::JarFinder.new(/.*spring-boot-(\d.*)\.jar/) end # Caches the dependencies of a Thin Launcher application by execute the application with +dryRun+ diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index 5a98ff1347..dacd564d83 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -89,11 +89,14 @@ def major_or_minor_and_tail(s) tail = nil else raise "Invalid version '#{s}': must not end in '.'" if s[-1] == '.' - raise "Invalid version '#{s}': missing component" if s =~ /\.[\._]/ + raise "Invalid version '#{s}': missing component" if s =~ /\.[._]/ - tokens = s.match(/^([^\.]+)(?:\.(.*))?/) + tokens = s.match(/^([^.]+)(?:\.(.*))?/) + # disable as we still have to support Ruby 2.5, remove & update when we drop Bionic support + # rubocop:disable Style/SlicingWithRange major_or_minor, tail = tokens[1..-1] + # rubocop:enable Style/SlicingWithRange raise "Invalid major or minor version '#{major_or_minor}'" unless valid_major_minor_or_micro major_or_minor end @@ -108,9 +111,12 @@ def micro_and_qualifier(s) else raise "Invalid version '#{s}': must not end in '_'" if s[-1] == '_' - tokens = s.match(/^([^\_]+)(?:_(.*))?/) + tokens = s.match(/^([^_]+)(?:_(.*))?/) + # disable as we still have to support Ruby 2.5, remove & update when we drop Bionic support + # rubocop:disable Style/SlicingWithRange micro, qualifier = tokens[1..-1] + # rubocop:enable Style/SlicingWithRange raise "Invalid micro version '#{micro}'" unless valid_major_minor_or_micro micro raise "Invalid qualifier '#{qualifier}'" unless valid_qualifier qualifier @@ -144,23 +150,27 @@ def non_nil_qualifier(qualifier) def validate(allow_wildcards) wildcarded = false each do |value| - if !value.nil? && value.end_with?(WILDCARD) && !allow_wildcards + if ends_with_wildcard(value) && !allow_wildcards raise "Invalid version '#{@version}': wildcards are not allowed this context" end raise "Invalid version '#{@version}': no characters are allowed after a wildcard" if wildcarded && value - wildcarded = true if !value.nil? && value.end_with?(WILDCARD) + wildcarded = true if ends_with_wildcard(value) end raise "Invalid version '#{@version}': missing component" if !wildcarded && compact.length < 3 end + def ends_with_wildcard(value) + !value.nil? && value.end_with?(WILDCARD) + end + def valid_major_minor_or_micro(major_minor_or_micro) - major_minor_or_micro =~ /^[\d]*$/ || major_minor_or_micro =~ /^\+$/ + major_minor_or_micro =~ /^\d*$/ || major_minor_or_micro =~ /^\+$/ end def valid_qualifier(qualifier) - qualifier.nil? || qualifier.empty? || qualifier =~ /^[-\.a-zA-Z\d]*[\+]?$/ + qualifier.nil? || qualifier.empty? || qualifier =~ /^[-.a-zA-Z\d]*\+?$/ end end diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 0466338843..350c252167 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -102,7 +102,7 @@ def cache def cache_task(uri) task uri do |t| @monitor.synchronize { rake_output_message "Caching #{t.name}" } - cache.get(t.name) {} + cache.get(t.name) end uri @@ -110,7 +110,7 @@ def cache_task(uri) def component_ids conf = configuration('components').values.flatten.map { |component| component.split('::').last.snake_case } - offline_cache = ENV['ADD_TO_CACHE'] + offline_cache = ENV.fetch('ADD_TO_CACHE', nil) unless offline_cache.nil? offline_cache = offline_cache.split(',') (conf << offline_cache).flatten!.uniq! diff --git a/rakelib/package.rb b/rakelib/package.rb index 3470d0d7a1..ebbac99291 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -35,8 +35,8 @@ def self.version PLATFORMS = %w[bionic].freeze - STAGING_DIR = "#{BUILD_DIR}/staging" + STAGING_DIR = "#{BUILD_DIR}/staging".freeze - PACKAGE_NAME = "#{BUILD_DIR}/java-buildpack#{offline}-#{version}.zip" + PACKAGE_NAME = "#{BUILD_DIR}/java-buildpack#{offline}-#{version}.zip".freeze end diff --git a/rakelib/stage_buildpack_task.rb b/rakelib/stage_buildpack_task.rb index 0a67e7e4f8..b3259f6a62 100644 --- a/rakelib/stage_buildpack_task.rb +++ b/rakelib/stage_buildpack_task.rb @@ -52,7 +52,7 @@ def copy_task(source, target) def disable_remote_downloads_task file "#{STAGING_DIR}/config/cache.yml" do |t| content = File.open(t.source, 'r') { |f| f.read.gsub(/enabled/, 'disabled') } - File.open(t.name, 'w') { |f| f.write content } + File.open(t.name, 'w') { |f| File.write(f, content) } end end @@ -67,7 +67,7 @@ def version_task directory parent file target => [parent] do |t| File.open(t.name, 'w') do |f| - f.write(BUILDPACK_VERSION.to_hash.to_yaml) + File.write(f, BUILDPACK_VERSION.to_hash.to_yaml) end end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 0906a116d1..54c1e7bd1d 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -99,9 +99,11 @@ def initialize NOTE_LINKS = { 'access_logging_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, 'agent' => { 'cve' => '', 'release' => '' }, - 'app_dynamics_agent' => { 'cve' => '', - 'release' => '[Release Notes](https://docs.appdynamics.com/4.5.x/en/product-and-' \ - 'release-announcements/release-notes/language-agent-notes/java-agent-notes)' }, + 'app_dynamics_agent' => { + 'cve' => '', + 'release' => '[Release Notes](https://docs.appdynamics.com/4.5.x/en/product-and-' \ + 'release-announcements/release-notes/language-agent-notes/java-agent-notes)' + }, 'azure_application_insights_agent' => { 'cve' => '', 'release' => '[Release Notes](https://github.com/Microsoft/ApplicationInsights-Java/releases)' }, @@ -284,23 +286,7 @@ def dependency_versions configurations = component_ids.map { |component_id| component_configuration(component_id) }.flatten configurations.each do |configuration| - id = configuration['sub_component_id'] || configuration['component_id'] - - index_configuration(configuration).each do |index_configuration| - version, uri = get_from_cache(cache, configuration, index_configuration) - - name = NAME_MAPPINGS[id] - raise "Unable to resolve name for '#{id}'" unless name - - dependency_versions << { - 'id' => id, - 'name' => name, - 'uri' => uri, - 'version' => version, - 'cve_link' => NOTE_LINKS[id]['cve'], - 'release_notes_link' => NOTE_LINKS[id]['release'] - } - end + map_config_to_dependency(cache, configuration, dependency_versions) end dependency_versions @@ -308,6 +294,26 @@ def dependency_versions .sort_by { |dependency| dependency['id'] } end + def map_config_to_dependency(cache, configuration, dependency_versions) + id = configuration['sub_component_id'] || configuration['component_id'] + + index_configuration(configuration).each do |index_configuration| + version, uri = get_from_cache(cache, configuration, index_configuration) + + name = NAME_MAPPINGS[id] + raise "Unable to resolve name for '#{id}'" unless name + + dependency_versions << { + 'id' => id, + 'name' => name, + 'uri' => uri, + 'version' => version, + 'cve_link' => NOTE_LINKS[id]['cve'], + 'release_notes_link' => NOTE_LINKS[id]['release'] + } + end + end + def index_configuration(configuration) [configuration['repository_root']] .map { |r| { uri: r } } @@ -359,7 +365,7 @@ def version_markdown_task .sort_by { |dependency| dependency['name'].downcase } .each do |dependency| puts "| #{dependency['name']} | `#{dependency['version']}` |" \ - "#{dependency['cve_link']} | #{dependency['release_notes_link']} |" + "#{dependency['cve_link']} | #{dependency['release_notes_link']} |" end end end diff --git a/spec/console_helper.rb b/spec/console_helper.rb index 1c8133e6b4..26efb84df5 100644 --- a/spec/console_helper.rb +++ b/spec/console_helper.rb @@ -19,6 +19,7 @@ require 'tee' require 'java_buildpack/util/colorize' +# rubocop:disable Style/GlobalStdStream shared_context 'with console help' do STDOUT.sync @@ -60,3 +61,4 @@ def copy_stream(source, destination) end end +# rubocop:enable Style/GlobalStdStream diff --git a/spec/droplet_helper.rb b/spec/droplet_helper.rb index 962483b143..1e63d9a406 100644 --- a/spec/droplet_helper.rb +++ b/spec/droplet_helper.rb @@ -32,6 +32,7 @@ require 'java_buildpack/util/tokenized_version' require 'pathname' +# rubocop: disable RSpec/MultipleMemoizedHelpers shared_context 'with droplet help' do include_context 'with application help' include_context 'with logging help' @@ -88,8 +89,8 @@ FileUtils.cp_r 'spec/fixtures/additional_libs/.', additional_libs_directory additional_libs_directory.children.each { |child| additional_libraries << child } - extension_directories << sandbox + 'test-extension-directory-1' - extension_directories << sandbox + 'test-extension-directory-2' + extension_directories << (sandbox + 'test-extension-directory-1') + extension_directories << (sandbox + 'test-extension-directory-2') FileUtils.cp_r 'spec/fixtures/root_libs/.', root_libs_directory root_libs_directory.children.each { |child| root_libraries << child } @@ -98,3 +99,4 @@ end end +# rubocop: enable RSpec/MultipleMemoizedHelpers diff --git a/spec/java_buildpack/buildpack_spec.rb b/spec/java_buildpack/buildpack_spec.rb index 6953e0ea11..738118b21d 100644 --- a/spec/java_buildpack/buildpack_spec.rb +++ b/spec/java_buildpack/buildpack_spec.rb @@ -161,7 +161,9 @@ end def with_buildpack(&_) + # rubocop:disable Style/ExplicitBlockArgument described_class.with_buildpack(app_dir, nil, nil, 'Error %s') { |buildpack| yield buildpack } + # rubocop:enable Style/ExplicitBlockArgument end end diff --git a/spec/java_buildpack/component/additional_libraries_spec.rb b/spec/java_buildpack/component/additional_libraries_spec.rb index f93ccdb824..a1c57896cc 100644 --- a/spec/java_buildpack/component/additional_libraries_spec.rb +++ b/spec/java_buildpack/component/additional_libraries_spec.rb @@ -37,8 +37,8 @@ end it 'renders as classpath' do - additional_libraries << droplet.sandbox + 'jar-2.jar' - additional_libraries << droplet.sandbox + 'jar-1.jar' + additional_libraries << (droplet.sandbox + 'jar-2.jar') + additional_libraries << (droplet.sandbox + 'jar-1.jar') expect(additional_libraries.as_classpath).to eq('-cp $PWD/.java-buildpack/additional_libraries/jar-1.jar:' \ '$PWD/.java-buildpack/additional_libraries/jar-2.jar') diff --git a/spec/java_buildpack/component/base_component_spec.rb b/spec/java_buildpack/component/base_component_spec.rb index 3fafba9677..301f9687f6 100644 --- a/spec/java_buildpack/component/base_component_spec.rb +++ b/spec/java_buildpack/component/base_component_spec.rb @@ -84,7 +84,7 @@ it 'prints timing information' do expect { |b| component.with_timing('test-caption', &b) }.to yield_control - expect(stdout.string).to match(/ test-caption \([\d]\.[\d]s\)/) + expect(stdout.string).to match(/ test-caption \(\d\.\ds\)/) end end diff --git a/spec/java_buildpack/component/extension_directories_spec.rb b/spec/java_buildpack/component/extension_directories_spec.rb index 215e53e81d..a033e49aad 100644 --- a/spec/java_buildpack/component/extension_directories_spec.rb +++ b/spec/java_buildpack/component/extension_directories_spec.rb @@ -35,8 +35,8 @@ end it 'renders as path' do - extension_directories << droplet.sandbox + 'extension-directories-1' - extension_directories << droplet.sandbox + 'extension-directories-2' + extension_directories << (droplet.sandbox + 'extension-directories-1') + extension_directories << (droplet.sandbox + 'extension-directories-2') expect(extension_directories.as_paths).to eq('$PWD/.java-buildpack/extension_directories/' \ 'extension-directories-1:$PWD/.java-buildpack/' \ diff --git a/spec/java_buildpack/component/immutable_java_home_spec.rb b/spec/java_buildpack/component/immutable_java_home_spec.rb index 8f1285bbef..ed87ac7840 100644 --- a/spec/java_buildpack/component/immutable_java_home_spec.rb +++ b/spec/java_buildpack/component/immutable_java_home_spec.rb @@ -23,7 +23,7 @@ describe JavaBuildpack::Component::ImmutableJavaHome do let(:delegate) do - instance_double(JavaBuildpack::Component::MutableJavaHome, + instance_double('JavaBuildpack::Component::MutableJavaHome', root: Pathname.new('test-java-home'), java_8_or_later?: true, java_9_or_later?: true, diff --git a/spec/java_buildpack/component/modular_component_spec.rb b/spec/java_buildpack/component/modular_component_spec.rb index 811adf4e09..65df02ffa5 100644 --- a/spec/java_buildpack/component/modular_component_spec.rb +++ b/spec/java_buildpack/component/modular_component_spec.rb @@ -78,6 +78,7 @@ end +# rubocop:disable Lint/UselessMethodDefinition class StubModularComponent < JavaBuildpack::Component::ModularComponent def command @@ -93,3 +94,4 @@ def supports? end end +# rubocop:enable Lint/UselessMethodDefinition diff --git a/spec/java_buildpack/component/security_providers_spec.rb b/spec/java_buildpack/component/security_providers_spec.rb index 6f748c424a..8fe3f67390 100644 --- a/spec/java_buildpack/component/security_providers_spec.rb +++ b/spec/java_buildpack/component/security_providers_spec.rb @@ -41,7 +41,7 @@ security_providers.write_to security_file expect(security_file.read).to eq("security.provider.1=test-security-provider-1\n" \ - "security.provider.2=test-security-provider-2\n") + "security.provider.2=test-security-provider-2\n") end end diff --git a/spec/java_buildpack/container/dist_zip_like_spec.rb b/spec/java_buildpack/container/dist_zip_like_spec.rb index 94eb404ee6..6130eb67cd 100644 --- a/spec/java_buildpack/container/dist_zip_like_spec.rb +++ b/spec/java_buildpack/container/dist_zip_like_spec.rb @@ -47,8 +47,8 @@ expect((app_dir + 'application-root/bin/application').read) .to match 'declare -r app_classpath="\$app_home/../../.additional_libs/test-jar-1.jar:' \ - '\$app_home/../../.additional_libs/test-jar-2.jar:\$app_home/../../.root_libs/test-jar-3.jar:' \ - '\$app_home/../../.root_libs/test-jar-4.jar:' + '\$app_home/../../.additional_libs/test-jar-2.jar:\$app_home/../../.root_libs/test-jar-3.jar:' \ + '\$app_home/../../.root_libs/test-jar-4.jar:' end it 'returns command', diff --git a/spec/java_buildpack/container/java_main_spec.rb b/spec/java_buildpack/container/java_main_spec.rb index c328b52f73..b743e29897 100644 --- a/spec/java_buildpack/container/java_main_spec.rb +++ b/spec/java_buildpack/container/java_main_spec.rb @@ -88,10 +88,10 @@ it 'returns command' do expect(component.release).to eq('test-var-2 test-var-1 ' \ - "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ - '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ - '.additional_libs/test-jar-2.jar:$PWD/.root_libs/test-jar-3.jar:' \ - '$PWD/.root_libs/test-jar-4.jar test-java-main-class') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ + '.additional_libs/test-jar-2.jar:$PWD/.root_libs/test-jar-3.jar:' \ + '$PWD/.root_libs/test-jar-4.jar test-java-main-class') end end @@ -99,11 +99,11 @@ app_fixture: 'container_main' do expect(component.release).to eq('test-var-2 test-var-1 ' \ - "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ - '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ - '.additional_libs/test-jar-2.jar:$PWD/alpha.jar:$PWD/bravo.jar:$PWD/' \ - 'charlie.jar:$PWD/.root_libs/test-jar-3.jar:$PWD/.root_libs/test-jar-4.jar ' \ - 'test-main-class') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/' \ + '.additional_libs/test-jar-2.jar:$PWD/alpha.jar:$PWD/bravo.jar:$PWD/' \ + 'charlie.jar:$PWD/.root_libs/test-jar-3.jar:$PWD/.root_libs/test-jar-4.jar ' \ + 'test-main-class') end context do @@ -112,10 +112,10 @@ it 'returns command line arguments when they are specified' do expect(component.release).to eq('test-var-2 test-var-1 ' \ - "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ - '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ - 'test-jar-2.jar:$PWD/.root_libs/test-jar-3.jar:' \ - '$PWD/.root_libs/test-jar-4.jar test-java-main-class some arguments') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.additional_libs/test-jar-1.jar:$PWD/.additional_libs/' \ + 'test-jar-2.jar:$PWD/.root_libs/test-jar-3.jar:' \ + '$PWD/.root_libs/test-jar-4.jar test-java-main-class some arguments') end end @@ -123,27 +123,27 @@ app_fixture: 'container_main_spring_boot_jar_launcher' do expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ - '-cp $PWD/.:$PWD/.root_libs/test-jar-3.jar:$PWD/.root_libs/test-jar-4.jar ' \ - 'org.springframework.boot.loader.JarLauncher') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.root_libs/test-jar-3.jar:$PWD/.root_libs/test-jar-4.jar ' \ + 'org.springframework.boot.loader.JarLauncher') end it 'releases Spring boot applications with a WarLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_war_launcher' do expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ - '-cp $PWD/.:$PWD/.root_libs/test-jar-3.jar:$PWD/.root_libs/test-jar-4.jar ' \ - 'org.springframework.boot.loader.WarLauncher') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.root_libs/test-jar-3.jar:$PWD/.root_libs/test-jar-4.jar ' \ + 'org.springframework.boot.loader.WarLauncher') end it 'releases Spring boot applications with a PropertiesLauncher in the MANIFEST.MF by specifying a port', app_fixture: 'container_main_spring_boot_properties_launcher' do expect(component.release).to eq('test-var-2 test-var-1 SERVER_PORT=$PORT ' \ - "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ - '-cp $PWD/.:$PWD/.root_libs/test-jar-3.jar:$PWD/.root_libs/test-jar-4.jar ' \ - 'org.springframework.boot.loader.PropertiesLauncher') + "eval exec #{qualify_path java_home.root, droplet.root}/bin/java $JAVA_OPTS " \ + '-cp $PWD/.:$PWD/.root_libs/test-jar-3.jar:$PWD/.root_libs/test-jar-4.jar ' \ + 'org.springframework.boot.loader.PropertiesLauncher') end it 'releases Spring Boot thin applications by specifying thin.root', diff --git a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb index 034a2bf65a..8463b23156 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_geode_store_spec.rb @@ -108,16 +108,18 @@ app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store-tomcat-multi-version.tar' do - expect { component.compile }.to raise_error RuntimeError, 'Multiple versions of geode-modules-tomcat jar found.' \ - ' Please verify your geode_store tar only contains one geode-modules-tomcat jar.' + # rubocop:disable Layout/LineLength + expect { component.compile }.to raise_error RuntimeError, 'Multiple versions of geode-modules-tomcat jar found. Please verify your geode_store tar only contains one geode-modules-tomcat jar.' + # rubocop:enable Layout/LineLength end it 'raises runtime error if no Geode Tomcat module jar is detected', app_fixture: 'container_tomcat_geode_store', cache_fixture: 'stub-geode-store-no-geode-tomcat.tar' do - expect { component.compile }.to raise_error RuntimeError, 'Geode Tomcat module not found. ' \ - 'Please verify your geode_store tar contains a geode-modules-tomcat jar.' + # rubocop:disable Layout/LineLength + expect { component.compile }.to raise_error RuntimeError, 'Geode Tomcat module not found. Please verify your geode_store tar contains a geode-modules-tomcat jar.' + # rubocop:enable Layout/LineLength end it 'mutates server.xml', diff --git a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb index edb540bc83..c65d0c2d88 100644 --- a/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb +++ b/spec/java_buildpack/container/tomcat/tomcat_instance_spec.rb @@ -67,7 +67,7 @@ cache_fixture: 'stub-tomcat.tar.gz' do component.compile - expect((sandbox + 'conf/context.xml').read).to match(%r{[\s]*}) + expect((sandbox + 'conf/context.xml').read).to match(%r{\s*}) expect((sandbox + 'conf/server.xml').read) .not_to match(%r{}) end diff --git a/spec/java_buildpack/container/tomcat_spec.rb b/spec/java_buildpack/container/tomcat_spec.rb index 4936e4d0a7..37dded2c4c 100644 --- a/spec/java_buildpack/container/tomcat_spec.rb +++ b/spec/java_buildpack/container/tomcat_spec.rb @@ -76,7 +76,7 @@ it 'creates submodules' do # create Tomcat instance double so we can pull version when creating submodules - tomcat_instance = instance_double(JavaBuildpack::Container::TomcatInstance) + tomcat_instance = instance_double('JavaBuildpack::Container::TomcatInstance') tomcat_instance.instance_variable_set(:@version, %w[9 0 44]) allow(JavaBuildpack::Container::TomcatInstance) diff --git a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb index cecf5d2b1e..96194396be 100644 --- a/spec/java_buildpack/framework/app_dynamics_agent_spec.rb +++ b/spec/java_buildpack/framework/app_dynamics_agent_spec.rb @@ -37,7 +37,7 @@ let(:credentials) { {} } before do - allow(services).to receive(:one_service?).with(/app[-]?dynamics/, 'host-name').and_return(true) + allow(services).to receive(:one_service?).with(/app-?dynamics/, 'host-name').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => credentials) end diff --git a/spec/java_buildpack/framework/contrast_security_agent_spec.rb b/spec/java_buildpack/framework/contrast_security_agent_spec.rb index e0a8a3222c..9ffb86cb90 100644 --- a/spec/java_buildpack/framework/contrast_security_agent_spec.rb +++ b/spec/java_buildpack/framework/contrast_security_agent_spec.rb @@ -74,7 +74,7 @@ component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/contrast_security_agent/contrast-engine-0.0.0.jar' \ - '=$PWD/.java-buildpack/contrast_security_agent/contrast.config') + '=$PWD/.java-buildpack/contrast_security_agent/contrast.config') expect(java_opts).to include('-Dcontrast.dir=$TMPDIR') expect(java_opts).to include('-Dcontrast.override.appname=test-application-name') end diff --git a/spec/java_buildpack/framework/datadog_javaagent_spec.rb b/spec/java_buildpack/framework/datadog_javaagent_spec.rb index 398688572e..75ec1889ed 100644 --- a/spec/java_buildpack/framework/datadog_javaagent_spec.rb +++ b/spec/java_buildpack/framework/datadog_javaagent_spec.rb @@ -32,25 +32,25 @@ subject(:detect) { component.detect } it 'does not detect without an api key' do - expect(detect).to be nil + expect(detect).to be_nil end context 'when api key is empty' do let(:environment) { { 'DD_API_KEY' => '' } } - it { is_expected.to be nil } + it { is_expected.to be_nil } end context 'when apm is disabled' do let(:environment) { { 'DD_API_KEY' => 'foo', 'DD_APM_ENABLED' => 'false' } } - it { is_expected.to be nil } + it { is_expected.to be_nil } end context 'when apm is enabled with no api key' do let(:environment) { { 'DD_APM_ENABLED' => 'true' } } - it { is_expected.to be nil } + it { is_expected.to be_nil } end context 'when apm key is provided' do diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index d2025b254a..92841c3fac 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -37,7 +37,7 @@ allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&' \ - 'Api-Token=test-apitoken') + 'Api-Token=test-apitoken') .and_yield(Pathname.new('spec/fixtures/stub-dynatrace-one-agent.zip').open, false) end @@ -60,7 +60,7 @@ component.release expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/dynatrace_one_agent/agent/lib64/' \ - 'liboneagentloader.so') + 'liboneagentloader.so') expect(java_opts).to include('-Xshare:off') end @@ -73,7 +73,7 @@ expect(environment_variables).to include('DT_TENANT=test-environmentid') expect(environment_variables).to include('DT_TENANTTOKEN=token-from-file') expect(environment_variables).to include('DT_CONNECTION_POINT=' \ - '"https://endpoint1/communication;https://endpoint2/communication"') + '"https://endpoint1/communication;https://endpoint2/communication"') end context do @@ -103,7 +103,7 @@ allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64&' \ - 'Api-Token=test-apitoken&networkZone=test-network-zone') + 'Api-Token=test-apitoken&networkZone=test-network-zone') .and_yield(Pathname.new('spec/fixtures/stub-dynatrace-one-agent.zip').open, false) end @@ -126,7 +126,7 @@ 'apitoken' => 'test-apitoken' }) allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64' \ - '&Api-Token=test-apitoken') + '&Api-Token=test-apitoken') .and_raise(RuntimeError.new('service interrupt')) end @@ -146,7 +146,7 @@ 'skiperrors' => 'true' }) allow(application_cache).to receive(:get) .with('test-apiurl/v1/deployment/installer/agent/unix/paas/latest?include=java&bitness=64' \ - '&Api-Token=test-apitoken') + '&Api-Token=test-apitoken') .and_raise(RuntimeError.new('service interrupt')) end @@ -160,7 +160,7 @@ component.release expect(java_opts).not_to include('-agentpath:$PWD/.java-buildpack/dynatrace_one_agent/agent/lib64/' \ - 'liboneagentloader.so') + 'liboneagentloader.so') end end diff --git a/spec/java_buildpack/framework/introscope_agent_spec.rb b/spec/java_buildpack/framework/introscope_agent_spec.rb index ec55a9712c..a529082344 100644 --- a/spec/java_buildpack/framework/introscope_agent_spec.rb +++ b/spec/java_buildpack/framework/introscope_agent_spec.rb @@ -83,7 +83,7 @@ expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=5001') expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ - 'com.wily.isengard.postofficehub.link.net.DefaultSocketFactory') + 'com.wily.isengard.postofficehub.link.net.DefaultSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') @@ -107,7 +107,7 @@ expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.host.DEFAULT=test-host-name') expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.port.DEFAULT=5001') expect(java_opts).to include('-Dintroscope.agent.enterprisemanager.transport.tcp.socketfactory.DEFAULT=' \ - 'com.wily.isengard.postofficehub.link.net.DefaultSocketFactory') + 'com.wily.isengard.postofficehub.link.net.DefaultSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') @@ -133,7 +133,7 @@ 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end end @@ -156,7 +156,7 @@ 'com.wily.isengard.postofficehub.link.net.SSLSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end end @@ -179,7 +179,7 @@ 'com.wily.isengard.postofficehub.link.net.HttpTunnelingSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end end @@ -202,7 +202,7 @@ 'com.wily.isengard.postofficehub.link.net.HttpTunnelingSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end end @@ -225,7 +225,7 @@ 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end end @@ -248,7 +248,7 @@ 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') end end @@ -274,7 +274,7 @@ 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') expect(java_opts).to include('-DagentManager.credential=test-credential-cccf-88-ae') end end @@ -301,7 +301,7 @@ 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') expect(java_opts).to include('-DagentManager.credential=test-credential-cccf-88-ae') end end @@ -329,7 +329,7 @@ 'com.wily.isengard.postofficehub.link.net.HttpsTunnelingSocketFactory') expect(java_opts).to include('-Dcom.wily.introscope.agent.agentName=$(expr "$VCAP_APPLICATION" : ' \ - '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') + '\'.*application_name[": ]*\\([A-Za-z0-9_-]*\\).*\')') expect(java_opts).to include('-DagentManager.credential=test-credential-cccf-88-ae') end end diff --git a/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb index 760ae58a6c..c70c640f79 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/agent_spec.rb @@ -55,7 +55,7 @@ expect(java_opts).not_to include('--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED') expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ - 'java-memory-assistant-1.2.3.jar') + 'java-memory-assistant-1.2.3.jar') expect(java_opts).to include('-Djma.enabled=true') expect(java_opts).to include('-Djma.check_interval=5s') @@ -129,7 +129,7 @@ component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ - 'java-memory-assistant-0.1.0.jar') + 'java-memory-assistant-0.1.0.jar') expect(java_opts).to include('-Djma.enabled=true') expect(java_opts).to include('-Djma.check_interval=10m') expect(java_opts).to include('\'-Djma.max_frequency=4/10h\'') @@ -176,7 +176,7 @@ component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ - 'java-memory-assistant-0.1.0.jar') + 'java-memory-assistant-0.1.0.jar') expect(java_opts).to include('\'-Djma.thresholds.heap=>600MB\'') expect(java_opts).to include('\'-Djma.thresholds.eden=< 30MB\'') @@ -197,7 +197,7 @@ component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ - 'java-memory-assistant-0.1.0.jar') + 'java-memory-assistant-0.1.0.jar') expect(java_opts).to include('-Djma.enabled=true') expect(java_opts).to include('-Djma.log_level=WARNING') @@ -218,7 +218,7 @@ component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/java_memory_assistant_agent/' \ - 'java-memory-assistant-0.1.0.jar') + 'java-memory-assistant-0.1.0.jar') expect(java_opts).to include('-Djma.enabled=true') expect(java_opts).to include('-Djma.log_level=INFO') @@ -280,7 +280,7 @@ it 'fails if log_level is not recognized' do expect { component.release }.to raise_exception 'Invalid value of the \'log_level\'' \ - ' property: \'ciao\'' + ' property: \'ciao\'' end end diff --git a/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb index 67452fc203..9838d33a67 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/clean_up_spec.rb @@ -57,7 +57,7 @@ expect(java_opts).to include('-Djma.command.interpreter=') expect(java_opts).to include('-Djma.execute.before=$PWD/.java-buildpack/java_memory_assistant_clean_up/' \ - 'cleanup') + 'cleanup') end end @@ -75,7 +75,7 @@ expect(java_opts).not_to include('-Djma.command.interpreter=') expect(java_opts).not_to include('-Djma.execute.before=$PWD/.java-buildpack/java_memory_assistant_clean_up/' \ - 'cleanup') + 'cleanup') end end @@ -91,7 +91,7 @@ expect(java_opts).not_to include('-Djma.command.interpreter=') expect(java_opts).not_to include('-Djma.execute.before=$PWD/.java-buildpack/java_memory_assistant_clean_up/' \ - 'cleanup') + 'cleanup') end end diff --git a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb index a189ce1a07..ac1b671d8d 100644 --- a/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant/heap_dump_folder_spec.rb @@ -70,7 +70,7 @@ expect(java_opts).to include('-Djma.heap_dump_folder="test/folder"') expect(environment_variables).to include('JMA_HEAP_DUMP_FOLDER=test/folder') - expect(log_contents).to match(%r{Heap dumps will be stored under \'test/folder\'}) + expect(log_contents).to match(%r{Heap dumps will be stored under 'test/folder'}) end end @@ -100,7 +100,7 @@ expect(java_opts).to include('-Djma.heap_dump_folder="/my_volume/test/folder"') expect(environment_variables).to include('JMA_HEAP_DUMP_FOLDER=/my_volume/test/folder') - expect(log_contents).to match(%r{Heap dumps will be stored under \'/my_volume/test/folder\'}) + expect(log_contents).to match(%r{Heap dumps will be stored under '/my_volume/test/folder'}) end end diff --git a/spec/java_buildpack/framework/java_opts_spec.rb b/spec/java_buildpack/framework/java_opts_spec.rb index 43a671a425..23d08bb8a2 100644 --- a/spec/java_buildpack/framework/java_opts_spec.rb +++ b/spec/java_buildpack/framework/java_opts_spec.rb @@ -42,7 +42,7 @@ context do let(:configuration) do { 'java_opts' => '-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=y ' \ - "-XX:OnOutOfMemoryError='kill -9 %p'" } + "-XX:OnOutOfMemoryError='kill -9 %p'" } end it 'adds split java_opts to context' do @@ -81,7 +81,7 @@ { 'java_opts' => '-Dtest=something.\\\$dollar.\\\\\\\slash' } end - it 'can escape non-escaped characters ' do + it 'can escape non-escaped characters' do component.release expect(java_opts).to include('-Dtest=something.\\$dollar.\\\slash') end diff --git a/spec/java_buildpack/framework/java_security_spec.rb b/spec/java_buildpack/framework/java_security_spec.rb index 878727bb74..b4d1c7a725 100644 --- a/spec/java_buildpack/framework/java_security_spec.rb +++ b/spec/java_buildpack/framework/java_security_spec.rb @@ -27,7 +27,7 @@ component.release expect(java_opts).to include('-Djava.ext.dirs=$PWD/.java-buildpack/java_security/test-extension-directory-1:' \ - '$PWD/.java-buildpack/java_security/test-extension-directory-2') + '$PWD/.java-buildpack/java_security/test-extension-directory-2') end it 'writes security provider security properties' do diff --git a/spec/java_buildpack/framework/jprofiler_profiler_spec.rb b/spec/java_buildpack/framework/jprofiler_profiler_spec.rb index eef3ca9b9a..3c38d4ba5b 100644 --- a/spec/java_buildpack/framework/jprofiler_profiler_spec.rb +++ b/spec/java_buildpack/framework/jprofiler_profiler_spec.rb @@ -46,7 +46,7 @@ component.release expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jprofiler_profiler/bin/linux-x64/' \ - 'libjprofilerti.so=port=8849,nowait') + 'libjprofilerti.so=port=8849,nowait') end @@ -57,7 +57,7 @@ component.release expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jprofiler_profiler/bin/linux-x64/' \ - 'libjprofilerti.so=port=8850,nowait') + 'libjprofilerti.so=port=8850,nowait') end end @@ -68,7 +68,7 @@ component.release expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/jprofiler_profiler/bin/linux-x64/' \ - 'libjprofilerti.so=port=8849') + 'libjprofilerti.so=port=8849') end end diff --git a/spec/java_buildpack/framework/multi_buildpack_spec.rb b/spec/java_buildpack/framework/multi_buildpack_spec.rb index a2b3aec06e..c795a08359 100644 --- a/spec/java_buildpack/framework/multi_buildpack_spec.rb +++ b/spec/java_buildpack/framework/multi_buildpack_spec.rb @@ -136,9 +136,9 @@ def dep_dir component.compile expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-1')}=" \ - 'test-key-1=test-value-1,test-key-2=test-value-2') + 'test-key-1=test-value-1,test-key-2=test-value-2') expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-2')}=" \ - 'test-key-1=test-value-1,test-key-2=test-value-2') + 'test-key-1=test-value-1,test-key-2=test-value-2') end it 'adds agentpaths_with_props during release', @@ -147,9 +147,9 @@ def dep_dir component.release expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-1')}=" \ - 'test-key-1=test-value-1,test-key-2=test-value-2') + 'test-key-1=test-value-1,test-key-2=test-value-2') expect(java_opts).to include("-agentpath:$PWD/#{qualify_path('/multi-test-agent-2')}=" \ - 'test-key-1=test-value-1,test-key-2=test-value-2') + 'test-key-1=test-value-1,test-key-2=test-value-2') end it 'adds bootclasspath_ps during compile', diff --git a/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb b/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb index 5f8de5678d..993a6daf89 100644 --- a/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb +++ b/spec/java_buildpack/framework/riverbed_appinternals_agent_spec.rb @@ -31,9 +31,9 @@ before do allow(services).to receive(:one_service?).with(/appinternals/).and_return(true) + p = Pathname.new('spec/fixtures/stub-riverbed-appinternals-agent.zip') allow(application_cache).to receive(:get).with('http://testfoobar/profiler.zip') - .and_yield(Pathname.new('spec/fixtures/'\ - 'stub-riverbed-appinternals-agent.zip').open, false) + .and_yield(p.open, false) end it 'detects with riverbed-appinternals-agent service' do diff --git a/spec/java_buildpack/framework/sky_walking_agent_spec.rb b/spec/java_buildpack/framework/sky_walking_agent_spec.rb index 91412ed72c..1ddff1cac2 100644 --- a/spec/java_buildpack/framework/sky_walking_agent_spec.rb +++ b/spec/java_buildpack/framework/sky_walking_agent_spec.rb @@ -35,7 +35,7 @@ let(:credentials) { {} } before do - allow(services).to receive(:one_service?).with(/sky[-]?walking/, 'servers').and_return(true) + allow(services).to receive(:one_service?).with(/sky-?walking/, 'servers').and_return(true) allow(services).to receive(:find_service).and_return('credentials' => credentials) end diff --git a/spec/java_buildpack/framework/your_kit_profiler_spec.rb b/spec/java_buildpack/framework/your_kit_profiler_spec.rb index dc47d97db2..46976f07ae 100644 --- a/spec/java_buildpack/framework/your_kit_profiler_spec.rb +++ b/spec/java_buildpack/framework/your_kit_profiler_spec.rb @@ -45,10 +45,11 @@ it 'updates JAVA_OPTS' do component.release + # rubocop:disable Layout/LineLength expect(java_opts).to include("-agentpath:$PWD/.java-buildpack/your_kit_profiler/your_kit_profiler-#{version}=" \ - 'dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/your_kit_profiler/logs,' \ - 'port=10001,sessionname=test-application-name') - + 'dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/your_kit_profiler/logs,' \ + 'port=10001,sessionname=test-application-name') + # rubocop:enable Layout/LineLength end context do @@ -57,9 +58,11 @@ it 'adds port from configuration to JAVA_OPTS if specified' do component.release + # rubocop:disable Layout/LineLength expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/your_kit_profiler/your_kit_profiler-' \ - "#{version}=dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/" \ - 'your_kit_profiler/logs,port=10002,sessionname=test-application-name') + "#{version}=dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/" \ + 'your_kit_profiler/logs,port=10002,sessionname=test-application-name') + # rubocop:enable Layout/LineLength end end @@ -69,9 +72,11 @@ it 'adds session name from configuration to JAVA_OPTS if specified' do component.release + # rubocop:disable Layout/LineLength expect(java_opts).to include('-agentpath:$PWD/.java-buildpack/your_kit_profiler/your_kit_profiler-' \ - "#{version}=dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/" \ - 'your_kit_profiler/logs,port=10001,sessionname=alternative-session-name') + "#{version}=dir=$PWD/.java-buildpack/your_kit_profiler/snapshots,logdir=$PWD/.java-buildpack/" \ + 'your_kit_profiler/logs,port=10001,sessionname=alternative-session-name') + # rubocop:enable Layout/LineLength end end diff --git a/spec/java_buildpack/jre/ibm_jre_spec.rb b/spec/java_buildpack/jre/ibm_jre_spec.rb index a0827c33b7..c671f4a391 100644 --- a/spec/java_buildpack/jre/ibm_jre_spec.rb +++ b/spec/java_buildpack/jre/ibm_jre_spec.rb @@ -59,9 +59,11 @@ class StubIbmJRE < JavaBuildpack::Jre::IbmJRE public :command, :sub_components + # rubocop:disable Lint/UselessMethodDefinition def supports? super end + # rubocop:enable Lint/UselessMethodDefinition end diff --git a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb index 343ecd8581..8c4a68a33e 100644 --- a/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_memory_calculator_spec.rb @@ -29,13 +29,13 @@ let(:java_home) do java_home = JavaBuildpack::Component::MutableJavaHome.new - java_home.version = version_8 + java_home.version = version8 return java_home end - let(:version_8) { JavaBuildpack::Util::TokenizedVersion.new('1.8.0_162') } + let(:version8) { JavaBuildpack::Util::TokenizedVersion.new('1.8.0_162') } - let(:version_9) { JavaBuildpack::Util::TokenizedVersion.new('9.0.4_11') } + let(:version9) { JavaBuildpack::Util::TokenizedVersion.new('9.0.4_11') } it 'copies executable to bin directory', cache_fixture: 'stub-memory-calculator.tar.gz' do @@ -86,14 +86,14 @@ it 'creates memory calculation command', app_fixture: 'jre_memory_calculator_application' do - java_home.version = version_8 + java_home.version = version8 command = component.memory_calculation_command expect(command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like_memory_calculator/bin/' \ - 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -loadedClasses=2 ' \ - '-poolType=metaspace -stackThreads=200 -vmOptions="$JAVA_OPTS") && echo JVM Memory ' \ - 'Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') + 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT -loadedClasses=2 ' \ + '-poolType=metaspace -stackThreads=200 -vmOptions="$JAVA_OPTS") && echo JVM Memory ' \ + 'Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY"') end it 'does not throw an error when a directory ends in .jar', @@ -118,7 +118,7 @@ it 'creates memory calculation command with headroom', app_fixture: 'jre_memory_calculator_application' do - java_home.version = version_8 + java_home.version = version8 command = component.memory_calculation_command @@ -135,7 +135,7 @@ it 'creates memory calculation command', app_fixture: 'jre_memory_calculator_application' do - java_home.version = version_9 + java_home.version = version9 command = component.memory_calculation_command diff --git a/spec/java_buildpack/jre/open_jdk_like_spec.rb b/spec/java_buildpack/jre/open_jdk_like_spec.rb index b5de59928e..e8cebf0447 100644 --- a/spec/java_buildpack/jre/open_jdk_like_spec.rb +++ b/spec/java_buildpack/jre/open_jdk_like_spec.rb @@ -31,9 +31,9 @@ let(:java_home) { JavaBuildpack::Component::MutableJavaHome.new } - let(:version_7) { JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } + let(:version7) { JavaBuildpack::Util::TokenizedVersion.new('1.7.0_+') } - let(:version_8) { JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } + let(:version8) { JavaBuildpack::Util::TokenizedVersion.new('1.8.0_+') } let(:configuration) do { 'jre' => jre_configuration, @@ -67,7 +67,7 @@ end it 'returns command for Java 7' do - java_home.version = version_7 + java_home.version = version7 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ ' -loadedClasses=0 -poolType=permgen -stackThreads=200 -vmOptions="$JAVA_OPTS")' \ @@ -77,7 +77,7 @@ end it 'returns command for Java 8' do - java_home.version = version_8 + java_home.version = version8 expect(component.command).to eq('CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_like/bin/' \ 'java-buildpack-memory-calculator-0.0.0 -totMemory=$MEMORY_LIMIT' \ ' -loadedClasses=0 -poolType=metaspace -stackThreads=200 -vmOptions="$JAVA_OPTS")' \ @@ -92,10 +92,11 @@ class StubOpenJDKLike < JavaBuildpack::Jre::OpenJDKLike public :command, :sub_components + # rubocop:disable Lint/UselessMethodDefinition def supports? super end - + # rubocop:enable Lint/UselessMethodDefinition end def sub_configuration_context(configuration) diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index 9a8c352e05..c082596df5 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -326,7 +326,18 @@ .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original - allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original + + # behavior changed between ruby 2 & 3 with how default hash kwargs are passed + # this causes different arguments for the mock based on the ruby version + # Remove this when we drop support for ruby 2 + case RUBY_VERSION + when /2\.\d+\.\d+/ + allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original + when /3\.\d+\.\d+/ + allow(Net::HTTP).to receive(:start).with('foo-uri', 80).and_call_original + else + raise 'unexpected ruby version' + end download_cache.get(uri) {} end @@ -337,7 +348,18 @@ allow(ca_certs_directory).to receive(:exist?).and_return(true) allow(Net::HTTP).to receive(:Proxy).and_call_original - allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original + + # behavior changed between ruby 2 & 3 with how default hash kwargs are passed + # this causes different arguments for the mock based on the ruby version + # Remove this when we drop support for ruby 2 + case RUBY_VERSION + when /2\.\d+\.\d+/ + allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original + when /3\.\d+\.\d+/ + allow(Net::HTTP).to receive(:start).with('foo-uri', 80).and_call_original + else + raise 'unexpected ruby version' + end download_cache.get(uri) {} end diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index 91fc98dcc6..fe5911bf0e 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -34,7 +34,7 @@ end it 'not load absent configuration file' do - pathname = instance_double(Pathname) + pathname = instance_double('Pathname') allow(Pathname).to receive(:new).and_return(pathname) allow(pathname).to receive(:exist?).and_return(false) @@ -53,7 +53,7 @@ context do before do - pathname = instance_double(Pathname) + pathname = instance_double('Pathname') allow(Pathname).to receive(:new).and_return(pathname) allow(pathname).to receive(:exist?).and_return(true) diff --git a/spec/java_buildpack/util/constantize_spec.rb b/spec/java_buildpack/util/constantize_spec.rb index 511478781d..611416f653 100644 --- a/spec/java_buildpack/util/constantize_spec.rb +++ b/spec/java_buildpack/util/constantize_spec.rb @@ -31,6 +31,8 @@ end module Test + # rubocop:disable Lint/EmptyClass class StubClass end + # rubocop:enable Lint/EmptyClass end diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index 31f21a96bc..93cd3634e1 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -16,6 +16,7 @@ # limitations under the License. require 'application_helper' +require 'logging_helper' require 'fileutils' require 'java_buildpack/util/filtering_pathname' require 'set' @@ -124,7 +125,7 @@ expect((filtering_target + 'bad') == (app_dir + 'bad')).to be_truthy end - # rubocop:disable Lint/UselessComparison, Style/CaseEquality + # rubocop:disable Style/CaseEquality, Lint/BinaryOperatorWithIdenticalOperands it 'compares to filtering pathnames using <=>' do expect((filtering_target + 'good') <=> (filtering_target + 'good')).to eq(0) expect((filtering_target + 'good') <=> (filtering_target + 'bad')).to eq(1) @@ -147,7 +148,7 @@ expect((filtering_target + 'good') === (filtering_target + 'good')).to be_truthy expect((filtering_target + 'bad') === (filtering_target + 'bad')).to be_truthy end - # rubocop:enable Lint/UselessComparison, Style/CaseEquality + # rubocop:enable Style/CaseEquality, Lint/BinaryOperatorWithIdenticalOperands it 'delegates relative_path_from' do target = filtering_target + 'test1' @@ -333,8 +334,8 @@ end it 'delegates if open is called on a mutable instance with permissions' do - allow(app_dir).to receive(:open).with('w', 0o755) - mutable_target.open('w', 0o755) { |_| } + allow(app_dir).to receive(:open).with('w', 0o755, {}) + mutable_target.open('w', 0o755, {}) { |_| } end it 'delegates if open is called on a mutable instance with permissions and options' do diff --git a/spec/java_buildpack/util/play/post22_spec.rb b/spec/java_buildpack/util/play/post22_spec.rb index 8b687be2e3..8ab4343678 100644 --- a/spec/java_buildpack/util/play/post22_spec.rb +++ b/spec/java_buildpack/util/play/post22_spec.rb @@ -44,25 +44,27 @@ expect((app_dir + 'bin/play-application').read) .to match 'declare -r app_classpath="\$app_home/../.additional_libs/test-jar-1.jar:' \ - '\$app_home/../.additional_libs/test-jar-2.jar:' + '\$app_home/../.additional_libs/test-jar-2.jar:' end it 'returns command' do + # rubocop:disable Layout/LineLength expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ - "#{java_home.as_env_var} exec $PWD/bin/play-application $(for I in $JAVA_OPTS ; do echo \"-J$I\" ; done)") + "#{java_home.as_env_var} exec $PWD/bin/play-application $(for I in $JAVA_OPTS ; do echo \"-J$I\" ; done)") + # rubocop:enable Layout/LineLength end context do let(:java_opts) do super() << '-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : \'.' \ - '*instance_id[": ]*"\([a-z0-9]\+\)".*\')' + '*instance_id[": ]*"\([a-z0-9]\+\)".*\')' end it 'allows options with expressions' do play_app.release expect(java_opts).to include('-Dappdynamics.agent.nodeName=$(expr "$VCAP_APPLICATION" : \'.' \ - '*instance_id[": ]*"\([a-z0-9]\+\)".*\')') + '*instance_id[": ]*"\([a-z0-9]\+\)".*\')') end end diff --git a/spec/java_buildpack/util/play/pre22_dist_spec.rb b/spec/java_buildpack/util/play/pre22_dist_spec.rb index c178059789..ddd05675f7 100644 --- a/spec/java_buildpack/util/play/pre22_dist_spec.rb +++ b/spec/java_buildpack/util/play/pre22_dist_spec.rb @@ -105,7 +105,7 @@ it 'returns command' do expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ - "#{java_home.as_env_var} exec $PWD/application-root/start $JAVA_OPTS") + "#{java_home.as_env_var} exec $PWD/application-root/start $JAVA_OPTS") end end @@ -120,13 +120,15 @@ it 'extends the classpath of a Play 2.1 dist application' do play_app.compile + # rubocop:disable Layout/LineLength expect((app_dir + 'application-root/start').read).to match 'classpath="\$scriptdir/../.additional_libs/' \ - 'test-jar-1.jar:\$scriptdir/../.additional_libs/test-jar-2.jar:' + 'test-jar-1.jar:\$scriptdir/../.additional_libs/test-jar-2.jar:' + # rubocop:enable Layout/LineLength end it 'returns command' do expect(play_app.release).to eq('test-var-2 test-var-1 PATH=$PWD/.test-java-home/bin:$PATH ' \ - "#{java_home.as_env_var} exec $PWD/application-root/start $JAVA_OPTS") + "#{java_home.as_env_var} exec $PWD/application-root/start $JAVA_OPTS") end end diff --git a/spec/java_buildpack/util/spring_boot_utils_spec.rb b/spec/java_buildpack/util/spring_boot_utils_spec.rb index 4da647c399..b7213179ec 100644 --- a/spec/java_buildpack/util/spring_boot_utils_spec.rb +++ b/spec/java_buildpack/util/spring_boot_utils_spec.rb @@ -107,8 +107,10 @@ utils.cache_thin_dependencies java_home.root, 'test-application-root', 'test-thin-root' + # rubocop:disable Layout/LineLength expect(utils).to have_received(:shell).with("#{java_home.root + 'bin/java'} -Dthin.dryrun " \ - '-Dthin.root=test-thin-root -cp test-application-root org.springframework.boot.loader.wrapper.ThinJarWrapper') + '-Dthin.root=test-thin-root -cp test-application-root org.springframework.boot.loader.wrapper.ThinJarWrapper') + # rubocop:enable Layout/LineLength end end diff --git a/spec/logging_helper.rb b/spec/logging_helper.rb index 332789050f..0a914a3294 100644 --- a/spec/logging_helper.rb +++ b/spec/logging_helper.rb @@ -26,8 +26,8 @@ include_context 'with console help' include_context 'with application help' - previous_log_config = ENV['JBP_CONFIG_LOGGING'] - previous_log_level = ENV['JBP_LOG_LEVEL'] + previous_log_config = ENV.fetch('JBP_CONFIG_LOGGING', nil) + previous_log_level = ENV.fetch('JBP_LOG_LEVEL', nil) previous_debug_level = $DEBUG previous_verbose_level = $VERBOSE diff --git a/spec/memory_limit_helper.rb b/spec/memory_limit_helper.rb index 25850b5a0d..cd206fd819 100644 --- a/spec/memory_limit_helper.rb +++ b/spec/memory_limit_helper.rb @@ -19,7 +19,7 @@ shared_context 'with memory limit help' do - previous_memory_limit = ENV['MEMORY_LIMIT'] + previous_memory_limit = ENV.fetch('MEMORY_LIMIT', nil) before do |example| memory_limit = example.metadata[:memory_limit] From d6e4447d618d3f7b5f3ded19b10eb4443ff0e003 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 9 May 2022 22:22:45 -0400 Subject: [PATCH 677/812] Switch Luna download URLs (#942) The Luna Security Provider site went down. Thales has provided the binaries and we have relocated them to the standard download repository. This may be temporary, it's not clear at this time, but it will get the buildpack back and working again. It has been broken since the site went down. Signed-off-by: Daniel Mikusa --- config/luna_security_provider.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/luna_security_provider.yml b/config/luna_security_provider.yml index 352b8265eb..e79f7103a1 100644 --- a/config/luna_security_provider.yml +++ b/config/luna_security_provider.yml @@ -16,7 +16,7 @@ # Configuration for the Luna Security Provider framework --- version: 7.+ -repository_root: https://files.cf-hsm.io/luna-installer +repository_root: "{default.repository.root}/luna-security-provider" ha_logging_enabled: true logging_enabled: false tcp_keep_alive_enabled: false From 0487a68d48e6402a5cf1a48894562882c0ff4519 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Tue, 10 May 2022 13:59:27 -0400 Subject: [PATCH 678/812] Disable ProtectApp (#943) The ProtectApp download site has gone offline. This PR disables ProtectApp. You can re-enable it if you are able to how your own repository for the downloads. Signed-off-by: Daniel Mikusa --- config/components.yml | 1 - config/protect_app_security_provider.yml | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/components.yml b/config/components.yml index fdfc151f54..e419aadfab 100644 --- a/config/components.yml +++ b/config/components.yml @@ -66,7 +66,6 @@ frameworks: - "JavaBuildpack::Framework::MetricWriter" - "JavaBuildpack::Framework::NewRelicAgent" - "JavaBuildpack::Framework::PostgresqlJDBC" - - "JavaBuildpack::Framework::ProtectAppSecurityProvider" - "JavaBuildpack::Framework::RiverbedAppinternalsAgent" - "JavaBuildpack::Framework::SealightsAgent" - "JavaBuildpack::Framework::SeekerSecurityProvider" diff --git a/config/protect_app_security_provider.yml b/config/protect_app_security_provider.yml index 2f65c2475d..04fa1c23b2 100644 --- a/config/protect_app_security_provider.yml +++ b/config/protect_app_security_provider.yml @@ -14,6 +14,9 @@ # limitations under the License. # Configuration for the ProtectApp Security Provider framework + +# You must specify a the repository root of an ProtectApp repository. Please see the documentation for more detail. +# e.g. repository_root: "https://example.com/protectapp-installer/" --- version: 8.+ -repository_root: https://files.cf-hsm.io/protectapp-installer +repository_root: "" From 465a556f03f9cd772ecc4119b03f42eeb37ba874 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 11 May 2022 09:18:40 -0400 Subject: [PATCH 679/812] Fixes package bug introduced in refactoring (#944) PR #941 introduced a bug in packaging that wasn't caught by unit tests. The removal of this empty block generated a LocalJumpError. This PR adds it back and tells rubocop to ignore the empty block. Signed-off-by: Daniel Mikusa --- rakelib/dependency_cache_task.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 350c252167..1d05ee4a06 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -102,7 +102,9 @@ def cache def cache_task(uri) task uri do |t| @monitor.synchronize { rake_output_message "Caching #{t.name}" } - cache.get(t.name) + # rubocop:disable Lint/EmptyBlock + cache.get(t.name) {} + # rubocop:enable Lint/EmptyBlock end uri From 25db632f9757dc5656d80a9f95b1d8fff4279918 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 11 May 2022 16:05:55 -0400 Subject: [PATCH 680/812] Permit raw type values in Elastic APM config (#946) Resolves #935 Signed-off-by: Daniel Mikusa --- .../framework/elastic_apm_agent.rb | 2 +- .../framework/elastic_apm_agent_spec.rb | 52 ++++++++++--------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/java_buildpack/framework/elastic_apm_agent.rb b/lib/java_buildpack/framework/elastic_apm_agent.rb index bba02c8f33..5ff72b8a0f 100644 --- a/lib/java_buildpack/framework/elastic_apm_agent.rb +++ b/lib/java_buildpack/framework/elastic_apm_agent.rb @@ -90,7 +90,7 @@ def apply_user_configuration(credentials, configuration) def write_java_opts(java_opts, configuration) configuration.each do |key, value| - if /\$[({][^)}]+[)}]/ =~ value + if /\$[({][^)}]+[)}]/ =~ value.to_s # we need \" because this is a system property which ends up inside `JAVA_OPTS` which is already quoted java_opts.add_system_property("elastic.apm.#{key}", "\\\"#{value}\\\"") else diff --git a/spec/java_buildpack/framework/elastic_apm_agent_spec.rb b/spec/java_buildpack/framework/elastic_apm_agent_spec.rb index 9b74ddaab0..98c5c3caf9 100644 --- a/spec/java_buildpack/framework/elastic_apm_agent_spec.rb +++ b/spec/java_buildpack/framework/elastic_apm_agent_spec.rb @@ -59,30 +59,34 @@ expect(java_opts).to include('-Delastic.apm.log_file_name=STDOUT') end - it 'updates JAVA_OPTS with additional options' do - val = 'object_name[java.lang:type=Memory] attribute[HeapMemoryUsage:metric_name=test_heap_metric]' - shell = '$(echo \'Hello world!\') and stuff' - var = '--> ${SOME_VAR} <--' - allow(services).to receive(:find_service).and_return('credentials' => { 'secret_token' => 'test-secret_token', - 'server_urls' => 'different-serverurl', - 'service_name' => 'different-name', - 'foo' => 'bar', - 'capture_jmx_metrics' => val, - 'sub' => shell, - 'var' => var }) - - component.release - - expect(java_opts).to include('-Delastic.apm.secret_token=test-secret_token') - expect(java_opts).to include('-Delastic.apm.server_urls=different-serverurl') - expect(java_opts).to include('-Delastic.apm.service_name=different-name') - expect(java_opts).to include('-Delastic.apm.foo=bar') - escaped = 'object_name\[java.lang:type\=Memory\]\ attribute\[HeapMemoryUsage:metric_name\=test_heap_metric\]' - expect(java_opts).to include("-Delastic.apm.capture_jmx_metrics=#{escaped}") - expect(java_opts).to include('-Delastic.apm.sub=\"$(echo \'Hello world!\') and stuff\"') - expect(java_opts).to include('-Delastic.apm.var=\"--> ${SOME_VAR} <--\"') + context do + let(:creds) do + { 'secret_token' => 'test-secret_token', + 'server_urls' => 'different-serverurl', + 'service_name' => 'different-name', + 'foo' => 'bar', + 'capture_jmx_metrics' => 'object_name[java.lang:type=Memory] ' \ + 'attribute[HeapMemoryUsage:metric_name=test_heap_metric]', + 'sub' => '$(echo \'Hello world!\') and stuff', + 'var' => '--> ${SOME_VAR} <--', + 'bool' => false, + 'nil' => nil } + end + + it 'updates JAVA_OPTS with additional options' do + allow(services).to receive(:find_service).and_return('credentials' => creds) + + component.release + + expect(java_opts).to include('-Delastic.apm.secret_token=test-secret_token') + expect(java_opts).to include('-Delastic.apm.server_urls=different-serverurl') + expect(java_opts).to include('-Delastic.apm.service_name=different-name') + expect(java_opts).to include('-Delastic.apm.foo=bar') + escaped = 'object_name\[java.lang:type\=Memory\]\ attribute\[HeapMemoryUsage:metric_name\=test_heap_metric\]' + expect(java_opts).to include("-Delastic.apm.capture_jmx_metrics=#{escaped}") + expect(java_opts).to include('-Delastic.apm.sub=\"$(echo \'Hello world!\') and stuff\"') + expect(java_opts).to include('-Delastic.apm.var=\"--> ${SOME_VAR} <--\"') + end end - end - end From 68d20ef0a5a11ce172e0b722d2ac3dd7555fa18e Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Tue, 17 May 2022 13:38:15 -0400 Subject: [PATCH 681/812] Add deprecation warnings around SAR/SCC (#947) - Add a deprecation warning if you are manually including Spring Cloud Connectors in your app - Add a deprecation warning if you are relying on Spring Auto Reconfiguration, which has Spring Cloud Connectors shaded into it - Do not include Spring Auto Reconfiguration if java-cfenv JARs are present in the app Signed-off-by: Daniel Mikusa --- .../framework/spring_auto_reconfiguration.rb | 55 ++++++++++++++++++- .../WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar | 0 .../lib/java-cfenv-boot-2.1.2.RELEASE.jar | 0 .../lib/java-cfenv-jdbc-2.1.2.RELEASE.jar | 0 .../WEB-INF/lib/spring-core-3.2.3.RELEASE.jar | 0 ...ing-cloud-cloudfoundry-connector-1.2.3.jar | 0 .../WEB-INF/lib/spring-core-3.2.3.RELEASE.jar | 0 .../spring_auto_reconfiguration_spec.rb | 36 ++++++++++++ 8 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar create mode 100644 spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-boot-2.1.2.RELEASE.jar create mode 100644 spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-jdbc-2.1.2.RELEASE.jar create mode 100644 spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar create mode 100644 spec/fixtures/framework_auto_reconfiguration_scc/WEB-INF/lib/spring-cloud-cloudfoundry-connector-1.2.3.jar create mode 100644 spec/fixtures/framework_auto_reconfiguration_scc/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 295417371b..7c3ec11b1f 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -25,10 +25,19 @@ module Framework # applications. class SpringAutoReconfiguration < JavaBuildpack::Component::VersionedDependencyComponent + def initialize(context) + super(context) + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger SpringAutoReconfiguration + end + # (see JavaBuildpack::Component::BaseComponent#compile) def compile + log_warning_scc_manual if spring_cloud_connectors? + download_jar @droplet.additional_libraries << (@droplet.sandbox + jar_name) + + log_warning_sar_scc_auto end # (see JavaBuildpack::Component::BaseComponent#release) @@ -40,10 +49,52 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @configuration['enabled'] && (@droplet.root + '**/*spring-core*.jar').glob.any? + @configuration['enabled'] && spring? && !java_cfenv? end - end + private + + def spring? + (@droplet.root + '**/*spring-core*.jar').glob.any? + end + def java_cfenv? + (@droplet.root + '**/*java-cfenv*.jar').glob.any? + end + + def spring_cloud_connectors? + (@droplet.root + '**/spring-cloud-cloudfoundry-connector*.jar').glob.any? || + (@droplet.root + '**/spring-cloud-spring-service-connector*.jar').glob.any? + end + + def log_warning_scc_manual + @logger.warn do + 'ATTENTION: The Spring Cloud Connectors library is present in your application. This library ' \ + 'has been in maintenance mode since July 2019 and will stop receiving all updates after ' \ + 'Dec 2022.' + end + @logger.warn do + 'Please migrate to java-cfenv immediately. See https://via.vmw.com/EhzD for migration instructions.' \ + end + end + + def log_warning_sar_scc_auto + @logger.warn do + 'ATTENTION: The Spring Auto Reconfiguration and shaded Spring Cloud Connectors libraries are ' \ + 'being installed. These projects have been deprecated, are no longer receiving updates and should ' \ + 'not be used going forward.' + end + @logger.warn do + 'If you are not using these libraries, set `JBP_CONFIG_SPRING_AUTO_RECONFIGURATION=\'{enabled: false}\'` ' \ + 'to disable their installation and clear this warning message. The buildpack will switch its default ' \ + 'to disable by default after Aug 2022. Spring Auto Reconfiguration and its shaded Spring Cloud ' \ + 'Connectors will be removed from the buildpack after Dec 2022.' + end + @logger.warn do + 'If you are using these libraries, please migrate to java-cfenv immediately. ' \ + 'See https://via.vmw.com/EhzD for migration instructions. Once you upgrade this message will go away.' + end + end + end end end diff --git a/spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar b/spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-boot-2.1.2.RELEASE.jar b/spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-boot-2.1.2.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-jdbc-2.1.2.RELEASE.jar b/spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/java-cfenv-jdbc-2.1.2.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar b/spec/fixtures/framework_auto_reconfiguration_java_cfenv/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_auto_reconfiguration_scc/WEB-INF/lib/spring-cloud-cloudfoundry-connector-1.2.3.jar b/spec/fixtures/framework_auto_reconfiguration_scc/WEB-INF/lib/spring-cloud-cloudfoundry-connector-1.2.3.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_auto_reconfiguration_scc/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar b/spec/fixtures/framework_auto_reconfiguration_scc/WEB-INF/lib/spring-core-3.2.3.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index 8b66daad8b..d3f5cec59c 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -17,10 +17,13 @@ require 'spec_helper' require 'component_helper' +require 'logging_helper' require 'java_buildpack/framework/spring_auto_reconfiguration' describe JavaBuildpack::Framework::SpringAutoReconfiguration do include_context 'with component help' + include_context 'with console help' + include_context 'with logging help' let(:configuration) { { 'enabled' => true } } @@ -36,10 +39,43 @@ expect(component.detect).to eq("spring-auto-reconfiguration=#{version}") end + it 'does not detect with Spring JAR and java-cfenv', + app_fixture: 'framework_auto_reconfiguration_java_cfenv' do + + expect(component.detect).to be_nil + end + it 'does not detect without Spring JAR' do expect(component.detect).to be_nil end + it 'warns if SCC is present', + cache_fixture: 'stub-auto-reconfiguration.jar', + app_fixture: 'framework_auto_reconfiguration_scc' do + + component.compile + + expect(stderr.string).to match(/ATTENTION: The Spring Cloud Connectors library is present in your application/) + end + + it 'does not warn when SCC is missing', + cache_fixture: 'stub-auto-reconfiguration.jar', + app_fixture: 'framework_auto_reconfiguration_servlet_3' do + + component.compile + + expect(stderr.string).not_to match(/ATTENTION: The Spring Cloud Connectors library is present in your application/) + end + + it 'warns if SAR is contributed', + cache_fixture: 'stub-auto-reconfiguration.jar', + app_fixture: 'framework_auto_reconfiguration_servlet_3' do + + component.compile + + expect(stderr.string).to match(/ATTENTION: The Spring Auto Reconfiguration and shaded Spring Cloud/) + end + context do let(:configuration) { { 'enabled' => false } } From f73bdee55a6329c8bd2b6c495394df141dd0b56e Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 19 May 2022 15:59:15 -0400 Subject: [PATCH 682/812] Update deprecation link (#948) This new link points directly to a new section in the docs on migrations. The link target doesn't yet exist, but will once documentation updates are published. Signed-off-by: Daniel Mikusa --- lib/java_buildpack/framework/spring_auto_reconfiguration.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 7c3ec11b1f..92fc27ff07 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -74,7 +74,7 @@ def log_warning_scc_manual 'Dec 2022.' end @logger.warn do - 'Please migrate to java-cfenv immediately. See https://via.vmw.com/EhzD for migration instructions.' \ + 'Please migrate to java-cfenv immediately. See https://via.vmw.com/EiBW for migration instructions.' \ end end @@ -92,7 +92,7 @@ def log_warning_sar_scc_auto end @logger.warn do 'If you are using these libraries, please migrate to java-cfenv immediately. ' \ - 'See https://via.vmw.com/EhzD for migration instructions. Once you upgrade this message will go away.' + 'See https://via.vmw.com/EiBW for migration instructions. Once you upgrade this message will go away.' end end end From 5d5900c09576ca60bbf83c28461ae9f690367b5d Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Wed, 25 May 2022 12:14:42 -0400 Subject: [PATCH 683/812] Update framework-debug.md (#950) Change from using `-u none` to `-u process`, as `none` is no longer supported on CF. --- docs/framework-debug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-debug.md b/docs/framework-debug.md index adbf9e4b89..303ce3fe2b 100644 --- a/docs/framework-debug.md +++ b/docs/framework-debug.md @@ -22,7 +22,7 @@ The framework can be configured by creating or modifying the [`config/debug.yml` | ---- | ----------- | `enabled` | Whether to enable Java debugging | `port` | The port that the debug agent will listen on. Defaults to `8000`. -| `suspend` | Whether to suspend execution until a debugger has attached. Note, you cannot ssh to a container until the container has decided the application is running. Therefore when enabling this setting you must also push the application using the parameter `-u none` which disables container health checking. +| `suspend` | Whether to suspend execution until a debugger has attached. Note, you cannot ssh to a container until the container has decided the application is running. Therefore when enabling this setting you must also push the application using the parameter `-u process` which disables container health checking. ## Creating SSH Tunnel After starting an application with debugging enabled, an SSH tunnel must be created to the container. To create that SSH container, execute the following command: From d60eea9da09e7bcc6da29910be4ef48d7d0aa530 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 7 Jul 2022 14:10:53 -0400 Subject: [PATCH 684/812] Remove Takipi Agent (#956) The download site for the Takipi Agent has gone dark, and attempts to alert the vendor and rectify the situation have failed. This component will no longer be enabled with the default distribution of the Java buildpack. You can re-enable it if you are able to host your own repository for the downloads. If/when the vendor is able to resolve the situation, we can re-enable the agent by default in the buildpack. Signed-off-by: Daniel Mikusa --- config/components.yml | 1 - config/takipi_agent.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/config/components.yml b/config/components.yml index e419aadfab..ca7e43907c 100644 --- a/config/components.yml +++ b/config/components.yml @@ -73,6 +73,5 @@ frameworks: - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::SkyWalkingAgent" - "JavaBuildpack::Framework::YourKitProfiler" - - "JavaBuildpack::Framework::TakipiAgent" - "JavaBuildpack::Framework::JavaSecurity" - "JavaBuildpack::Framework::JavaOpts" diff --git a/config/takipi_agent.yml b/config/takipi_agent.yml index dd8407034e..7a30931bac 100644 --- a/config/takipi_agent.yml +++ b/config/takipi_agent.yml @@ -16,6 +16,6 @@ # Configuration for the Takipi framework --- version: 4.+ -repository_root: https://get.takipi.com/cloudfoundry +repository_root: "" node_name_prefix: node application_name: From 740d21b8879fc76ed070bbfcdf7514408bca7ea9 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Fri, 22 Jul 2022 13:21:18 -0400 Subject: [PATCH 685/812] Require missing library (#958) After refactoring for Ruby 3.0 compatibility, it looks like there's now a missing dependency. This PR adds the missing 'tempfile' require. Signed-off-by: Daniel Mikusa --- lib/java_buildpack/jre/ibm_jre_initializer.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/java_buildpack/jre/ibm_jre_initializer.rb b/lib/java_buildpack/jre/ibm_jre_initializer.rb index 4bf77a26ab..8b53ac9452 100644 --- a/lib/java_buildpack/jre/ibm_jre_initializer.rb +++ b/lib/java_buildpack/jre/ibm_jre_initializer.rb @@ -16,6 +16,7 @@ # limitations under the License. require 'fileutils' +require 'tempfile' require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/jre' require 'java_buildpack/util/tokenized_version' From e6cae92715dc327f74f78329dfc158c64221fbf7 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Fri, 22 Jul 2022 13:39:01 -0400 Subject: [PATCH 686/812] Bump release notes links for Java (#959) Signed-off-by: Daniel Mikusa --- rakelib/versions_task.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index 54c1e7bd1d..b0f21155b5 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -135,12 +135,12 @@ def initialize 'jprofiler_profiler' => { 'cve' => '', 'release' => '[ChangeLog](https://www.ej-technologies.com/download/jprofiler/changelog.html)' }, - 'jre' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u332/)' }, - 'jre-11' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.15/)' }, - 'jre-17' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.3/)' }, + 'jre' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u342/)' }, + 'jre-11' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.16/)' }, + 'jre-17' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)', + 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.4/)' }, 'jrebel_agent' => { 'cve' => '', 'release' => '[ChangeLog](https://www.jrebel.com/products/jrebel/changelog)' }, 'jvmkill_agent' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, 'lifecycle_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, From 0ea003c6ea89af434abc47f1408b1cf64604f796 Mon Sep 17 00:00:00 2001 From: ushaazul <107583423+ushaazul@users.noreply.github.com> Date: Mon, 25 Jul 2022 07:29:11 -0700 Subject: [PATCH 687/812] Add Azul Platform Prime to java-buildpack (#954) * Bug: n/a Reviewed-By: n/a Tests-Run: n/a modified: README.md modified: config/components.yml new file: config/zing_jre.yml new file: docs/jre-zing_jre.md new file: lib/java_buildpack/jre/zing_jre.rb * modified: config/zing_jre.yml modified: docs/jre-zing_jre.md * Removing installing Java kill agent and memory calculator modified: open_jdk_like.rb * Changes for Zing modified: ../../../lib/java_buildpack/jre/zing_jre.rb * Update zing_jre.rb * Remove changes from open_jdk_like.rb, Updating docs for Azul Prime JRE and some minor changes modified: docs/jre-zing_jre.md modified: lib/java_buildpack/jre/open_jdk_like.rb modified: lib/java_buildpack/jre/zing_jre.rb * Remove changes from open_jdk_like.rb and some minor changes to zing_jre.rb modified: lib/java_buildpack/jre/open_jdk_like.rb modified: lib/java_buildpack/jre/zing_jre.rb --- README.md | 1 + config/components.yml | 1 + config/zing_jre.yml | 33 +++++++ docs/jre-zing_jre.md | 146 +++++++++++++++++++++++++++++ lib/java_buildpack/jre/zing_jre.rb | 45 +++++++++ 5 files changed, 226 insertions(+) create mode 100755 config/zing_jre.yml create mode 100644 docs/jre-zing_jre.md create mode 100755 lib/java_buildpack/jre/zing_jre.rb diff --git a/README.md b/README.md index facf5b16ff..50167fbb99 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ The buildpack supports extension through the use of Git repository forking. The * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) * Standard JREs * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) + * [Azul Platform Prime](docs/jre-zing_jre.md) ([Configuration](docs/jre-zing_jre.md#configuration)) * [GraalVM](docs/jre-graal_vm_jre.md) ([Configuration](docs/jre-graal_vm_jre.md#configuration)) * [IBM® SDK, Java™ Technology Edition](docs/jre-ibm_jre.md) ([Configuration](docs/jre-ibm_jre.md#configuration)) * [OpenJDK](docs/jre-open_jdk_jre.md) ([Configuration](docs/jre-open_jdk_jre.md#configuration)) diff --git a/config/components.yml b/config/components.yml index ca7e43907c..9011950635 100644 --- a/config/components.yml +++ b/config/components.yml @@ -34,6 +34,7 @@ jres: - "JavaBuildpack::Jre::OpenJdkJRE" # - "JavaBuildpack::Jre::OracleJRE" # - "JavaBuildpack::Jre::ZuluJRE" +# - "JavaBuildpack::Jre::ZingJRE" # - "JavaBuildpack::Jre::SapMachineJRE" # Frameworks are processed in order. diff --git a/config/zing_jre.yml b/config/zing_jre.yml new file mode 100755 index 0000000000..d1631a4843 --- /dev/null +++ b/config/zing_jre.yml @@ -0,0 +1,33 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for JRE repositories keyed by vendor +# Pre Java 1.8, permgen was used instead of metaspace. Please see the documentation for more detail. + +# You must specify a the repository root of a Azul Platform Prime JRE repository. Please see the documentation for more detail. +# e.g. repository_root: "https://example.com/zing-jre/{platform}/{architecture}" +--- +jre: + version: 1.8.0_+ + repository_root: "" +jvmkill_agent: + version: 1.+ + repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" +memory_calculator: + version: 3.+ + repository_root: "{default.repository.root}/memory-calculator/{platform}/{architecture}" + class_count: + headroom: + stack_threads: 250 diff --git a/docs/jre-zing_jre.md b/docs/jre-zing_jre.md new file mode 100644 index 0000000000..8e4b097317 --- /dev/null +++ b/docs/jre-zing_jre.md @@ -0,0 +1,146 @@ +# Azul Platform Prime JRE +Azul Platform Prime JRE provides Java runtimes developed by Azul. No versions of the JRE are available by default due to licensing restrictions. Instead you will need to create a repository with the Prime JREs in it and configure the buildpack to use that repository. Unless otherwise configured, the version of Java that will be used is specified in [`config/zing_jre.yml`][]. + + + + + + + + + + +
Detection CriterionUnconditional. Existence of a single bound Volume Service will result in Terminal heap dumps being written. +
    +
  • Existence of a Volume Service service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has heap-dump as a substring.
  • +
+
Tagsopen-jdk-like-jre=⟨version⟩, open-jdk-like-memory-calculator=⟨version⟩, jvmkill=⟨version⟩
+Tags are printed to standard output by the buildpack detect script. + + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +The JRE can be configured by modifying the [`config/zing_jre.yml`][] file in the buildpack fork. The JRE uses the [`Repository` utility support][repositories] and so, it supports the [version syntax][] defined there. + +To use Azul Platform Prime JRE instead of OpenJDK without forking java-buildpack, set environment variable and restage: + +```bash +cf set-env JBP_CONFIG_COMPONENTS '{jres: ["JavaBuildpack::Jre::ZingJRE"]}' +cf set-env JBP_CONFIG_ZING_JRE '{ jre: { repository_root: "" } }' +cf restage +``` + +| Name | Description +| ---- | ----------- +| `jre.repository_root` | The URL of the Azul Platform Prime repository index ([details][repositories]). +| `jre.version` | The version of Java runtime to use. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. +| `memory_calculator` | Memory calculator defaults, described below under "Memory". + +### Additional Resources +The JRE can also be configured by overlaying a set of resources on the default distribution. To do this, add files to the `resources/zing_jre` directory in the buildpack fork. + +#### JCE Unlimited Strength +To add the JCE Unlimited Strength `local_policy.jar`, add your file to `resources/zing_jre/lib/security/local_policy.jar`. This file will be overlayed onto the Azul Platform Prime distribution. + +#### Custom CA Certificates +To add custom SSL certificates, add your `cacerts` file to `resources/zing_jre/lib/security/cacerts`. This file will be overlayed onto the Azul Platform Prime distribution. + +### `jvmkill` +Azul Platform Prime JRE does not use the jvmkill agent instead by default uses the -XX:ExitOnOutOfMemoryError flag which terminates the JVM process when an out-of-memory error occurs. + +If a [Volume Service][] with the string `heap-dump` in its name or tag is bound to the application, terminal heap dumps will be written with the pattern `/-/-/--.hprof` + +```plain +Heapdump written to /var/vcap/data/9ae0b817-1446-4915-9990-74c1bb26f147/pcfdev-space-e91c5c39/java-main-application-892f20ab/0-2017-06-13T18:31:29+0000-7b23124e.hprof +``` + +### Memory +The total available memory for the application's container is specified when an application is pushed. +The Java buildpack uses this value to control the JRE's use of various +regions of memory and logs the JRE memory settings when the application starts or restarts. +These settings can be influenced by configuring +the `stack_threads` and/or `class_count` mappings (both part of the `memory_calculator` mapping), +and/or Java options relating to memory. + +Note: If the total available memory is scaled up or down, the Java buildpack will re-calculate the JRE memory settings the next time the application is started. + +#### Total Memory + +The user can change the container's total memory available to influence the JRE memory settings. +Unless the user specifies the heap size Java option (`-Xmx`), increasing or decreasing the total memory +available results in the heap size setting increasing or decreasing by a corresponding amount. + +#### Loaded Classes + +The amount of memory that is allocated to metaspace and compressed class space (or, on Java 7, the permanent generation) is calculated from an estimate of the number of classes that will be loaded. The default behaviour is to estimate the number of loaded classes as a fraction of the number of class files in the application. +If a specific number of loaded classes should be used for calculations, then it should be specified as in the following example: + +```yaml +class_count: 500 +``` + +#### Headroom + +A percentage of the total memory allocated to the container to be left as headroom and excluded from the memory calculation. + +```yaml +headroom: 10 +``` + +#### Stack Threads + +The amount of memory that should be allocated to stacks is given as an amount of memory per thread with the Java option `-Xss`. If an explicit number of threads should be used for the calculation of stack memory, then it should be specified as in the following example: + +```yaml +stack_threads: 500 +``` + +Note that the default value of 250 threads is optimized for a default Tomcat configuration. If you are using another container, especially something non-blocking like Netty, it's more appropriate to use a significantly smaller value. Typically 25 threads would cover the needs of both the server (Netty) and the threads started by the JVM itself. + +#### Java Options + +If the JRE memory settings need to be fine-tuned, the user can set one or more Java memory options to +specific values. The heap size can be set explicitly, but changing the value of options other +than the heap size can also affect the heap size. For example, if the user increases +the maximum direct memory size from its default value of 10 Mb to 20 Mb, then this will +reduce the calculated heap size by 10 Mb. + +#### Memory Calculation +Memory calculation happens before every `start` of an application and is performed by an external program, the [Java Buildpack Memory Calculator]. There is no need to `restage` an application after scaling the memory as restarting will cause the memory settings to be recalculated. + +The container's total available memory is allocated into heap, metaspace and compressed class space (or permanent generation for Java 7), +direct memory, and stack memory settings. + +The memory calculation is described in more detail in the [Memory Calculator's README]. + +The inputs to the memory calculation, except the container's total memory (which is unknown at staging time), are logged during staging, for example: +``` +Loaded Classes: 13974, Threads: 300, JAVA_OPTS: '' +``` + +The container's total memory is logged during `cf push` and `cf scale`, for example: +``` + state since cpu memory disk details +#0 running 2017-04-10 02:20:03 PM 0.0% 896K of 1G 1.3M of 1G +``` + +The JRE memory settings are logged when the application is started or re-started, for example: +``` +JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199K \ + -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=18134K -Xss1M -Xmx368042K +``` + +[`config/components.yml`]: ../config/components.yml +[`config/zing_jre.yml`]: ../config/zing_jre.yml +[Azul Platform Prime]: https://www.azul.com/products/prime/ +[Configuration and Extension]: ../README.md#configuration-and-extension +[Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml +[Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator +[repositories]: extending-repositories.md +[version syntax]: extending-repositories.md#version-syntax-and-ordering +[Volume Service]: https://docs.cloudfoundry.org/devguide/services/using-vol-services.html +[Azul Platform Prime JRE]: jre-zing_jre.md diff --git a/lib/java_buildpack/jre/zing_jre.rb b/lib/java_buildpack/jre/zing_jre.rb new file mode 100755 index 0000000000..da98b63aa0 --- /dev/null +++ b/lib/java_buildpack/jre/zing_jre.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'fileutils' +require 'java_buildpack/jre' +require 'java_buildpack/jre/open_jdk_like' + +module JavaBuildpack + module Jre + + # Encapsulates the detect, compile, and release functionality for selecting an Azul Platform Prime JRE. + class ZingJRE < OpenJDKLike + def command + "" + end + + def sub_components(context) + [ + OpenJDKLikeJre.new(sub_configuration_context(context, 'jre') + .merge(component_name: self.class.to_s.space_case)), + OpenJDKLikeSecurityProviders.new(context) + ] + end + + def release + super + @droplet.add_preformatted_options "-XX:+ExitOnOutOfMemoryError" + end + end + end +end From 8f446a7421aa0f96b990d6e79e497cc62bd03251 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 28 Jul 2022 11:02:53 -0400 Subject: [PATCH 688/812] Fixes Rubocop complaints and adds missing method docs (#961) Signed-off-by: Daniel Mikusa --- lib/java_buildpack/jre/zing_jre.rb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/java_buildpack/jre/zing_jre.rb b/lib/java_buildpack/jre/zing_jre.rb index da98b63aa0..daa0c44589 100755 --- a/lib/java_buildpack/jre/zing_jre.rb +++ b/lib/java_buildpack/jre/zing_jre.rb @@ -24,21 +24,24 @@ module Jre # Encapsulates the detect, compile, and release functionality for selecting an Azul Platform Prime JRE. class ZingJRE < OpenJDKLike + # (see JavaBuildpack::Component::ModularComponent#command) def command - "" + '' end + # (see JavaBuildpack::Component::ModularComponent#sub_components) def sub_components(context) - [ - OpenJDKLikeJre.new(sub_configuration_context(context, 'jre') - .merge(component_name: self.class.to_s.space_case)), - OpenJDKLikeSecurityProviders.new(context) - ] + [ + OpenJDKLikeJre.new(sub_configuration_context(context, 'jre') + .merge(component_name: self.class.to_s.space_case)), + OpenJDKLikeSecurityProviders.new(context) + ] end - + + # (see JavaBuildpack::Component::BaseComponent#release) def release super - @droplet.add_preformatted_options "-XX:+ExitOnOutOfMemoryError" + @droplet.add_preformatted_options '-XX:+ExitOnOutOfMemoryError' end end end From 5fe41f892c3d005ce743ddff83c021757c60b9ab Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 28 Jul 2022 14:50:08 -0400 Subject: [PATCH 689/812] Add default functionality & refactor packaging (#957) 1. Adds an environment variable that can be used by operations teams to set default values. Operator defaults override buildpack defaults, but are overridden by application developer values. Operator defaults are set by exposing an environment variable of the pattern `JBP_DEFAULT_=''`. So to set a default Java version, `JBP_DEFAULT_OPEN_JDK_JRE='{ jre: { version: 11.+ }}'`. 2. Adds `config/packaging.yml`. This contains the list of component data. Each component gets a name, CVE notes link and release notes link. This information is used by the `rake versions` command to generate a nice set of release notes for each package. This information was refactored out of the scripts (was previously hard-coded). 3. Each `config/.yml` file has been given a `jre.version_lines` property. This is a list of the supported version lines for that JRE. It defaults to using pattern matching to pick the latest 1.8, 11 and 17 versions. If you are packaging your own version of the buildpack and want to limit the version lines included, perhaps to reduce the size of the generated buildpack file, you can edit this list and remove entries. Theh package script will only include what is listed in this array. 4. When pinning versions, the packaging script will now update each `config/yml` file's `jre.version_lines` list with the pinned versions, in addition to `jre.version`. This allows you to have a list of every version line bundled with the buildpack when a release is cut (previously, only 1.8 was committed to source control). This helps when rebuilding a version of the Java buildpack at a later date, as you'll have the exact set of Java versions which should be included. 5. You may change the default version of Java that is selected during a build of the Java buildpack by setting the `config/.yml` file's `jre.version` value. This needs to match one of the entries in `jre.version_lines`. Then follow the standard packaging steps the the buildpack that's generated will use the selected version of Java by default. Signed-off-by: Daniel Mikusa --- .idea/runConfigurations/All_Tests__2_5_.xml | 4 +- .idea/runConfigurations/All_Tests__2_7_.xml | 4 +- .idea/runConfigurations/All_Tests__3_0_.xml | 4 +- .../Without_Integration_Tests__2_5_.xml | 4 +- .../Without_Integration_Tests__2_7_.xml | 4 +- .../Without_Integration_Tests__3_0_.xml | 4 +- README.md | 72 +++- config/graal_vm_jre.yml | 5 +- config/ibm_jre.yml | 4 +- config/open_jdk_jre.yml | 5 +- config/oracle_jre.yml | 4 + config/packaging.yml | 190 ++++++++++ config/sap_machine_jre.yml | 3 + config/zulu_jre.yml | 3 + java-buildpack.iml | 344 +++++++++++++++--- .../util/configuration_utils.rb | 31 +- rakelib/dependency_cache_task.rb | 79 ++-- rakelib/package.rb | 40 ++ rakelib/utils.rb | 61 ++++ rakelib/versions_task.rb | 190 +--------- .../util/configuration_utils_spec.rb | 60 +++ 21 files changed, 800 insertions(+), 315 deletions(-) create mode 100644 config/packaging.yml create mode 100644 rakelib/utils.rb diff --git a/.idea/runConfigurations/All_Tests__2_5_.xml b/.idea/runConfigurations/All_Tests__2_5_.xml index e2694fee68..679ca51e5e 100644 --- a/.idea/runConfigurations/All_Tests__2_5_.xml +++ b/.idea/runConfigurations/All_Tests__2_5_.xml @@ -2,7 +2,7 @@ - + @@ -10,7 +10,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__2_7_.xml b/.idea/runConfigurations/All_Tests__2_7_.xml index 4f9031d53b..fcde938296 100644 --- a/.idea/runConfigurations/All_Tests__2_7_.xml +++ b/.idea/runConfigurations/All_Tests__2_7_.xml @@ -2,7 +2,7 @@ - + @@ -10,7 +10,7 @@ - + diff --git a/.idea/runConfigurations/All_Tests__3_0_.xml b/.idea/runConfigurations/All_Tests__3_0_.xml index 6dd0b62d5b..e0118a93ec 100644 --- a/.idea/runConfigurations/All_Tests__3_0_.xml +++ b/.idea/runConfigurations/All_Tests__3_0_.xml @@ -2,7 +2,7 @@ - + @@ -10,7 +10,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml index bd9dbbf1f5..43ee491dd2 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_5_.xml @@ -2,7 +2,7 @@ - + @@ -10,7 +10,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__2_7_.xml b/.idea/runConfigurations/Without_Integration_Tests__2_7_.xml index 6432e7e234..a95a86acf7 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__2_7_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__2_7_.xml @@ -2,7 +2,7 @@ - + @@ -10,7 +10,7 @@ - + diff --git a/.idea/runConfigurations/Without_Integration_Tests__3_0_.xml b/.idea/runConfigurations/Without_Integration_Tests__3_0_.xml index 33a62d88ac..221ce17870 100644 --- a/.idea/runConfigurations/Without_Integration_Tests__3_0_.xml +++ b/.idea/runConfigurations/Without_Integration_Tests__3_0_.xml @@ -2,7 +2,7 @@ - + @@ -10,7 +10,7 @@ - + diff --git a/README.md b/README.md index 50167fbb99..8f527237c1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cloud Foundry Java Buildpack -The `java-buildpack` is a [Cloud Foundry][] buildpack for running JVM-based applications. It is designed to run many JVM-based applications ([Grails][], [Groovy][], Java Main, [Play Framework][], [Spring Boot][], and Servlet) with no additional configuration, but supports configuration of the standard components, and extension to add custom components. +The `java-buildpack` is a [Cloud Foundry][] buildpack for running JVM-based applications. It is designed to run many JVM-based applications ([Grails][], [Groovy][], Java Main, [Play Framework][], [Spring Boot][], and Servlet) with no additional configuration, but supports configuration of the standard components, and extension to add custom components. ## Usage To use this buildpack specify the URI of the repository when pushing an application to Cloud Foundry: @@ -21,38 +21,70 @@ The following are _very_ simple examples for deploying the artifact types that w * [Spring Boot CLI](docs/example-spring_boot_cli.md) ## Configuration and Extension -The buildpack default configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension and with a prefix of `JBP_CONFIG`. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack (in this case you will have to extend the buildpack, see below). The value of the variable should be valid inline yaml, referred to as "flow style" in the yaml spec ([Wikipedia][] has a good description of this yaml syntax). For example, to change the default version of Java to 11 and adjust the memory heuristics apply this environment variable to the application. + +The buildpack default configuration can be overridden with an environment variable matching the configuration file you wish to override minus the `.yml` extension. It is not possible to add new configuration properties and properties with `nil` or empty values will be ignored by the buildpack (in this case you will have to extend the buildpack, see below). The value of the variable should be valid inline yaml, referred to as "flow style" in the yaml spec ([Wikipedia][] has a good description of this yaml syntax). + +There are two levels of overrides: operator and application developer. + + - If you are an operator that wishes to override configuration across a foundation, you may do this by setting environment variable group entries that begin with a prefix of `JBP_DEFAULT`. + - If you are an application developer that wishes to override configuration for an individual application, you may do this by setting environment variables that begin with a prefix of `JBP_CONFIG`. + +Here are some examples: + +### Operator + +1. To change the default version of Java to 11 across all applications on a foundation. + +```bash +$ cf set-staging-environment-variable-group '{"JBP_DEFAULT_OPEN_JDK_JRE":"{jre: {version: 11.+ }}"}' +``` + +2. To change the default repository root across all applications on a foundation. Be careful to ensure that your JSON is properly escaped. + +```bash +$ cf set-staging-environment-variable-group '{"JBP_CONFIG_REPOSITORY": "{default_repository_root: \"http://repo.example.io\" }"}' +``` + +3. To change the default JVM vendor across all applications on a foundation. Be careful to ensure that your JSON is properly escaped. + +```bash +$ cf set-staging-environment-variable-group '{"JBP_CONFIG_COMPONENTS": "{jres: [\"JavaBuildpack::Jre::ZuluJRE\"]}"}' +``` + +### Application Developer + +1. To change the default version of Java to 11 and adjust the memory heuristics then apply this environment variable to the application. ```bash $ cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ jre: { version: 11.+ }, memory_calculator: { stack_threads: 25 } }' ``` -If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. +2. If the key or value contains a special character such as `:` it should be escaped with double quotes. For example, to change the default repository path for the buildpack. ```bash $ cf set-env my-application JBP_CONFIG_REPOSITORY '{ default_repository_root: "http://repo.example.io" }' ``` -If the key or value contains an environment variable that you want to bind at runtime you need to escape it from your shell. For example, to add command line arguments containing an environment variable to a [Java Main](docs/container-java_main.md) application. +3. If the key or value contains an environment variable that you want to bind at runtime you need to escape it from your shell. For example, to add command line arguments containing an environment variable to a [Java Main](docs/container-java_main.md) application. ```bash $ cf set-env my-application JBP_CONFIG_JAVA_MAIN '{ arguments: "--server.port=9090 --foo=bar" }' ``` -An example of configuration is to specify a `javaagent` that is packaged within an application. +4. An example of configuration is to specify a `javaagent` that is packaged within an application. ```bash $ cf set-env my-application JAVA_OPTS '-javaagent:app/META-INF/myagent.jar -Dmyagent.config_file=app/META-INF/my_agent.conf' ``` -Environment variable can also be specified in the applications `manifest` file. For example, to specify an environment variable in an applications manifest file that disables Auto-reconfiguration. +5. Environment variable can also be specified in the applications `manifest` file. For example, to specify an environment variable in an applications manifest file that disables Auto-reconfiguration. ```bash env: JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{ enabled: false }' ``` -This final example shows how to change the version of Tomcat that is used by the buildpack with an environment variable specified in the applications manifest file. +6. This final example shows how to change the version of Tomcat that is used by the buildpack with an environment variable specified in the applications manifest file. ```bash env: @@ -63,7 +95,7 @@ See the [Environment Variables][] documentation for more information. To learn how to configure various properties of the buildpack, follow the "Configuration" links below. -The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. More information on extending the buildpack is available [here](docs/extending.md). +The buildpack supports extension through the use of Git repository forking. The easiest way to accomplish this is to use [GitHub's forking functionality][] to create a copy of this repository. Make the required extension changes in the copy of the repository. Then specify the URL of the new repository when pushing Cloud Foundry applications. If the modifications are generally applicable to the Cloud Foundry community, please submit a [pull request][] with the changes. More information on extending the buildpack is available [here](docs/extending.md). ## Additional Documentation * [Design](docs/design.md) @@ -141,12 +173,12 @@ The buildpack supports extension through the use of Git repository forking. The * [jvmkill](https://github.com/cloudfoundry/jvmkill) ## Building Packages -The buildpack can be packaged up so that it can be uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used. +The buildpack can be packaged up so that it can be uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used. Note that this process is not currently supported on Windows. It is possible it will work, but it is not tested, and no additional functionality has been added to make it work. ### Online Package -The online package is a version of the buildpack that is as minimal as possible and is configured to connect to the network for all dependencies. This package is about 50K in size. To create the online package, run: +The online package is a version of the buildpack that is as minimal as possible and is configured to connect to the network for all dependencies. This package is about 250K in size. To create the online package, run: ```bash $ bundle install @@ -156,7 +188,7 @@ Creating build/java-buildpack-cfd6b17.zip ``` ### Offline Package -The offline package is a version of the buildpack designed to run without access to a network. It packages the latest version of each dependency (as configured in the [`config/` directory][]) and [disables `remote_downloads`][]. This package is about 180M in size. To create the offline package, use the `OFFLINE=true` argument: +The offline package is a version of the buildpack designed to run without access to a network. It packages the latest version of each dependency (as configured in the [`config/` directory][]) and [disables `remote_downloads`][]. To create the offline package, use the `OFFLINE=true` argument: To pin the version of dependencies used by the buildpack to the ones currently resolvable use the `PINNED=true` argument. This will update the [`config/` directory][] to contain exact version of each dependency instead of version ranges. ```bash @@ -166,7 +198,11 @@ $ bundle exec rake clean package OFFLINE=true PINNED=true Creating build/java-buildpack-offline-cfd6b17.zip ``` -Only packages referenced in the [`config/components.yml` file](config/components.yml) will be cached. Additional packages may be added using the `ADD_TO_CACHE` argument. The value of `ADD_TO_CACHE` should be set to the name of a `.yml` file in the [`config/` directory][] with the `.yml` file extension omitted (e.g. `sap_machine_jre`). Multiple file names may be separated by commas. This is useful to add additional JREs. These additional components will not be enabled by default and must be explicitly enabled in the application with the `JBP_CONFIG_COMPONENTS` environment variable. +If you would rather specify the exact version to which the buildpack should bundle, you may manually edit the [`config/` file](`config/`) for the component and indicate the specific version to use. For most components, there is a single `version` property which defaults to a pattern to match the latest version. By setting the `version` property to a fixed version, the buildpack will install that exact version when you run the package command. For JRE config files, like [`config/open_jdk_jre.yml`](config/open_jdk_jre.yml), you need to set the `version_lines` array to include the specific version you'd like to install. By default, the `version_lines` array is going to have a pattern entry for each major version line that matches to the latest patch version. You can override the items in the `version_lines` array to set a specific versions to use when packaging the buildpack. For a JRE, the `jre.version` property is used to set the default version line and must match one of the entries in the `version_lines` property. + +This package size will vary depending on what dependencies are included. You can reduce the size by removing unused components, because only packages referenced in the [`config/components.yml` file](config/components.yml) will be cached. In addition, you can remove entries from the `version_lines` array in JRE configuration files, this removes that JRE version line, to further reduce the file size. + +Additional packages may be added using the `ADD_TO_CACHE` argument. The value of `ADD_TO_CACHE` should be set to the name of a `.yml` file in the [`config/` directory][] with the `.yml` file extension omitted (e.g. `sap_machine_jre`). Multiple file names may be separated by commas. This is useful to add additional JREs. These additional components will not be enabled by default and must be explicitly enabled in the application with the `JBP_CONFIG_COMPONENTS` environment variable. ```bash $ bundle install @@ -179,7 +215,7 @@ Creating build/java-buildpack-offline-cfd6b17.zip ``` ### Package Versioning -Keeping track of different versions of the buildpack can be difficult. To help with this, the rake `package` task puts a version discriminator in the name of the created package file. The default value for this discriminator is the current Git hash (e.g. `cfd6b17`). To change the version when creating a package, use the `VERSION=` argument: +Keeping track of different versions of the buildpack can be difficult. To help with this, the rake `package` task puts a version discriminator in the name of the created package file. The default value for this discriminator is the current Git hash (e.g. `cfd6b17`). To change the version when creating a package, use the `VERSION=` argument: ```bash $ bundle install @@ -190,9 +226,13 @@ Creating build/java-buildpack-2.1.zip ### Packaging Caveats -1. When pinning versions, only the default JRE version is pinned. There is [special handling to package additional versions of a JRE](https://github.com/cloudfoundry/java-buildpack/blob/main/rakelib/dependency_cache_task.rb#L128-L144) and the way this works, it will pick the latest version at the time you package not at the time of the version's release. -2. The `index.yml` file for a dependencie is packaged in the buildpack cache when building offline buildpacks. The `index.yml` file isn't versioned with the release, so if you package an offline buildpack for an older release, it will pull the current `index.yml`, not the one from the time of the release. This can result in errors if a user tells the buildpack to install the latest version of a default dependency, because the latest version is calculated from the `index.yml` file which has more recent versions than what are packaged in the offline buildpack. Because of #1, this only impacts the default JRE. Non-default JREs always package the most recent version, which is also the most recent version in `index.yml` at the time you package the offline buildpack. -3. Because of #1 and #2, it is not present to accurately reproduce packages of the buildpack, after releases have been cut. If building pinning or offline buildpacks, it is suggested to build them as soon as possible after a release is cut and save the produced artifact. +1. Prior to version 4.51 when pinning versions, only the default JRE version is pinned. There is [special handling to package additional versions of a JRE](https://github.com/cloudfoundry/java-buildpack/blob/main/rakelib/dependency_cache_task.rb#L128-L144) and the way this works, it will pick the latest version at the time you package not at the time of the version's release. Starting with version 4.51, the version number for all JRE version lines is tracked in the `config/` file. + +2. The `index.yml` file for a dependency is packaged in the buildpack cache when building offline buildpacks. The `index.yml` file isn't versioned with the release, so if you package an offline buildpack later after the release was tagged, it will pull the current `index.yml`, not the one from the time of the release. This can result in errors at build time if a user tells the buildpack to install the latest version of a dependency because the latest version is calculated from the `index.yml` file which has more recent versions than what are packaged in the offline buildpack. For example, if the user says give me Java `11._+` and the buildpack is pinned to Java `11.0.13_8` but at the time you packaged the buildpack the latest version in `index.yml` is `11.0.15_10` then the user will get an error. The buildpack will want to install `11.0.15_10` but it won't be present because `11.0.13_8` is all that's in the buildpack. + + Because of #1 for versions prior to 4.51, this only impacts the default JRE. Non-default JREs always package the most recent version, which is also the most recent version in `index.yml` at the time you package the offline buildpack. For 4.51 and up, this can impact all versions. + +4. Because of #1 and #2, it is not possible to accurately reproduce packages of the buildpack, after releases have been cut. If building pinned or offline buildpacks, it is suggested to build them as soon as possible after a release is cut and save the produced artifact. Alternatively, you would need to maintain your own buildpack dependency repository and keep snapshots of the buildpack dependency repository for each buildpack release you'd like to be able to rebuild. See [#892](https://github.com/cloudfoundry/java-buildpack/issues/892#issuecomment-880212806) for additional details. diff --git a/config/graal_vm_jre.yml b/config/graal_vm_jre.yml index b36d34f9b8..94419a9183 100644 --- a/config/graal_vm_jre.yml +++ b/config/graal_vm_jre.yml @@ -18,7 +18,10 @@ # e.g. repository_root: "https://example.com/graalvm-jre/{platform}/{architecture}" --- jre: - version: 19.3.+ + version: 22.1.+ + version_lines: + - 22.1.+ + - 21.3.+ repository_root: "" jvmkill_agent: version: 1.+ diff --git a/config/ibm_jre.yml b/config/ibm_jre.yml index 39b5c3d944..4446537109 100644 --- a/config/ibm_jre.yml +++ b/config/ibm_jre.yml @@ -18,7 +18,9 @@ --- jre: version: 1.8.+ - repository_root: https://raw.githubusercontent.com/ibmruntimes/ci.docker/master/ibmjava/meta/jre/linux/x86_64 + version_lines: + - 1.8.+ + repository_root: https://raw.githubusercontent.com/ibmruntimes/ci.docker/master/ibmjava/meta/jre/linux/{architecture} heap_ratio: 0.75 jvmkill_agent: version: 1.+ diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 2cee774cf4..27b70a03bd 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -14,10 +14,13 @@ # limitations under the License. # Configuration for JRE repositories keyed by vendor -# If Java 7 is required, permgen will be used instead of metaspace. Please see the documentation for more detail. --- jre: version: 1.8.0_+ + version_lines: + - 1.8.0_+ + - 11.+ + - 17.+ repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" jvmkill_agent: version: 1.+ diff --git a/config/oracle_jre.yml b/config/oracle_jre.yml index df91cc2e26..a24848b28c 100644 --- a/config/oracle_jre.yml +++ b/config/oracle_jre.yml @@ -21,6 +21,10 @@ --- jre: version: 1.8.0_+ + version_lines: + - 1.8.0_+ + - 11.+ + - 17.+ repository_root: "" jvmkill_agent: version: 1.+ diff --git a/config/packaging.yml b/config/packaging.yml new file mode 100644 index 0000000000..31bb350dd0 --- /dev/null +++ b/config/packaging.yml @@ -0,0 +1,190 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2022 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +access_logging_support: + name: Tomcat Access Logging Support + cve_notes: Included inline above + release_notes: Included inline above + +agent: + name: Java Memory Assistant Agent + +app_dynamics_agent: + name: AppDynamics Agent + release_notes: '[Release Notes](https://docs.appdynamics.com/4.5.x/en/product-and-release-announcements/release-notes/language-agent-notes/java-agent-notes)' + +azure_application_insights_agent: + name: Azure Application Insights Agent + release_notes: '[Release Notes](https://github.com/Microsoft/ApplicationInsights-Java/releases)' + +clean_up: + name: Java Memory Assistant Clean Up + +client_certificate_mapper: + name: Client Certificate Mapper + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +container_customizer: + name: Spring Boot Container Customizer + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +container_security_provider: + name: Container Security Provider + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +contrast_security_agent: + name: Contrast Security Agent + release_notes: '[Release Notes](https://docs.contrastsecurity.com/en/java-agent-release-notes.html)' + +datadog_javaagent: + name: Datadog APM Javaagent + release_notes: '[Release Notes](https://github.com/DataDog/dd-trace-java/releases)' + +dynatrace_one_agent: + name: Dynatrace OneAgent + release_notes: '[Release Notes](https://www.dynatrace.com/support/help/whats-new/release-notes/#oneagent)' + +elastic_apm_agent: + name: Elastic APM Agent + release_notes: '[Release Notes](https://www.elastic.co/guide/en/apm/agent/java/current/release-notes.html)' + +geode_store: + name: Geode Tomcat Session Store + +google_stackdriver_debugger: + name: Google Stackdriver Debugger + release_notes: '[Release Notes](https://cloud.google.com/debugger/docs/release-notes)' + +google_stackdriver_profiler: + name: Google Stackdriver Profiler + release_notes: '[Release Notes](https://cloud.google.com/profiler/docs/release-notes)' + +groovy: + name: Groovy + release_notes: '[Release Notes](http://www.groovy-lang.org/releases.html)' + +introscope_agent: + name: CA Introscope APM Framework + +jacoco_agent: + name: JaCoCo Agent + release_notes: '[Release Notes](https://github.com/jacoco/jacoco/releases)' + +jprofiler_profiler: + name: JProfiler Profiler + release_notes: '[ChangeLog](https://www.ej-technologies.com/download/jprofiler/changelog.html)' + +jre: + name: OpenJDK JRE 8 + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u342/)' + +jre-11: + name: OpenJDK JRE 11 + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.16/)' + +jre-17: + name: OpenJDK JRE 17 + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.4/)' + +jrebel_agent: + name: JRebel Agent + release_notes: '[ChangeLog](https://www.jrebel.com/products/jrebel/changelog)' + +jvmkill_agent: + name: jvmkill Agent + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +lifecycle_support: + name: Tomcat Lifecycle Support + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +logging_support: + name: Tomcat Logging Support + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +luna_security_provider: + name: Gemalto Luna Security Provider + release_notes: '[Release Notes](https://www.thalesdocs.com/gphsm/luna/7/docs/network/Content/CRN/Luna/CRN_Luna.htm)' + +maria_db_jdbc: + name: MariaDB JDBC Driver + release_notes: '[Release Notes](https://mariadb.com/kb/en/mariadb-connector-j-274-release-notes/)' + +memory_calculator: + name: Memory Calculator + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +metric_writer: + name: Metric Writer + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +new_relic_agent: + name: New Relic Agent + release_notes: '[Release Notes](https://docs.newrelic.com/docs/release-notes/agent-release-notes/java-release-notes/)' + +postgresql_jdbc: + name: PostgreSQL JDBC Driver + release_notes: '[ChangeLog](https://jdbc.postgresql.org/documentation/changelog.html)' + +protect_app_security_provider: + name: Gemalto ProtectApp Security Provider + +redis_store: + name: Redis Session Store + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +riverbed_appinternals_agent: + name: Riverbed Appinternals Agent + +sealights_agent: + name: SeaLights Agent + +sky_walking_agent: + name: SkyWalking + release_notes: '[ChangeLog](https://github.com/apache/skywalking/tree/master/changes)' + +spring_auto_reconfiguration: + name: Spring Auto-reconfiguration + cve_notes: 'Included inline above' + release_notes: 'Included inline above' + +spring_boot_cli: + name: Spring Boot CLI + +takipi_agent: + name: Takipi Agent + release_notes: '[Release Notes](https://doc.overops.com/docs/whats-new)' + +tomcat: + name: Tomcat + cve_notes: '[Security](https://tomcat.apache.org/security-9.html)' + release_notes: '[ChangeLog](https://tomcat.apache.org/tomcat-9.0-doc/changelog.html)' + +your_kit_profiler: + name: YourKit Profiler + release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2022_3_builds.jsp)' diff --git a/config/sap_machine_jre.yml b/config/sap_machine_jre.yml index ef8fb554fb..c0784cded4 100644 --- a/config/sap_machine_jre.yml +++ b/config/sap_machine_jre.yml @@ -18,6 +18,9 @@ --- jre: version: 11.+ + version_lines: + - 11.+ + - 17.+ repository_root: "https://sap.github.io/SapMachine/assets/cf/jre/linux/{architecture}" jvmkill_agent: version: 1.+ diff --git a/config/zulu_jre.yml b/config/zulu_jre.yml index 231b659ccb..5b8f41e05e 100755 --- a/config/zulu_jre.yml +++ b/config/zulu_jre.yml @@ -21,6 +21,9 @@ --- jre: version: 1.8.0_+ + version_lines: + - 1.8.0_+ + - 11.+ repository_root: "https://cdn.azul.com/zulu/bin" jvmkill_agent: version: 1.+ diff --git a/java-buildpack.iml b/java-buildpack.iml index c156f343b4..2b50d9c2eb 100644 --- a/java-buildpack.iml +++ b/java-buildpack.iml @@ -9,7 +9,7 @@ - + @@ -35,7 +35,7 @@ - + @@ -61,7 +61,7 @@ - + @@ -87,7 +87,7 @@ - + @@ -113,7 +113,7 @@ - + @@ -143,7 +143,7 @@ - + @@ -181,7 +181,7 @@ - + @@ -225,7 +225,7 @@ - + @@ -263,7 +263,7 @@ - + @@ -307,7 +307,7 @@ - + @@ -345,7 +345,7 @@ - + @@ -386,39 +386,301 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
\ No newline at end of file diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index c50ae73be7..687ebaa7c7 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -45,9 +45,13 @@ def load(identifier, clean_nil_values = true, should_log = true) file = file_name(identifier) if file.exist? - var_name = environment_variable_name(identifier) - user_provided = ENV.fetch(var_name, nil) - configuration = load_configuration(file, user_provided, var_name, clean_nil_values, should_log) + operator_var_name = default_variable_name(identifier) + operator_provided = ENV.fetch(operator_var_name, nil) + + user_var_name = environment_variable_name(identifier) + user_provided = ENV.fetch(user_var_name, nil) + configuration = load_configuration(file, operator_provided, operator_var_name, user_provided, + user_var_name, clean_nil_values, should_log) elsif should_log logger.debug { "No configuration file #{file} found" } end @@ -80,6 +84,7 @@ def write(identifier, new_content, should_log = true) CONFIG_DIRECTORY = Pathname.new(File.expand_path('../../../config', File.dirname(__FILE__))).freeze + DEFAULT_VARIABLE_PATTERN = 'JBP_DEFAULT_' ENVIRONMENT_VARIABLE_PATTERN = 'JBP_CONFIG_' private_constant :CONFIG_DIRECTORY, :ENVIRONMENT_VARIABLE_PATTERN @@ -112,16 +117,26 @@ def header(file) header end - def load_configuration(file, user_provided, var_name, clean_nil_values, should_log) + def load_configuration(file, operator_provided, operator_var_name, user_provided, user_var_name, + clean_nil_values, should_log) configuration = YAML.load_file(file) logger.debug { "Configuration from #{file}: #{configuration}" } if should_log + if operator_provided + begin + operator_provided_value = YAML.safe_load(operator_provided) + configuration = merge_configuration(configuration, operator_provided_value, operator_var_name, should_log) + rescue Psych::SyntaxError => e + raise "Default configuration value in environment variable #{operator_var_name} has invalid syntax: #{e}" + end + end + if user_provided begin user_provided_value = YAML.safe_load(user_provided) - configuration = merge_configuration(configuration, user_provided_value, var_name, should_log) + configuration = merge_configuration(configuration, user_provided_value, user_var_name, should_log) rescue Psych::SyntaxError => e - raise "User configuration value in environment variable #{var_name} has invalid syntax: #{e}" + raise "User configuration value in environment variable #{user_var_name} has invalid syntax: #{e}" end logger.debug { "Configuration from #{file} modified with: #{user_provided}" } if should_log end @@ -161,6 +176,10 @@ def do_resolve_value(key, v1, v2, should_log) v1 end + def default_variable_name(config_name) + DEFAULT_VARIABLE_PATTERN + config_name.upcase + end + def environment_variable_name(config_name) ENVIRONMENT_VARIABLE_PATTERN + config_name.upcase end diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 1d05ee4a06..01a1512a47 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -36,6 +36,8 @@ class DependencyCacheTask < Rake::TaskLib def initialize return unless BUILDPACK_VERSION.offline + @pkgcfg = nil + JavaBuildpack::Logging::LoggerFactory.instance.setup "#{BUILD_DIR}/" @default_repository_root = default_repository_root @@ -120,39 +122,6 @@ def component_ids conf end - def configuration(id) - JavaBuildpack::Util::ConfigurationUtils.load(id, false, false) - end - - def configurations(component_id, configuration, sub_component_id = nil) - configurations = [] - - if repository_configuration?(configuration) - configuration['component_id'] = component_id - configuration['sub_component_id'] = sub_component_id if sub_component_id - - if component_id == 'open_jdk_jre' && sub_component_id == 'jre' - c1 = configuration.clone - c1['version'] = '11.+' - - configurations << c1 - end - - if component_id == 'open_jdk_jre' && sub_component_id == 'jre' - c1 = configuration.clone - c1['version'] = '17.+' - - configurations << c1 - end - - configurations << configuration - else - configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } - end - - configurations - end - def component_configuration(component_id) configurations(component_id, configuration(component_id)) end @@ -161,19 +130,6 @@ def default_repository_root configuration('repository')['default_repository_root'].chomp('/') end - def index_configuration(configuration) - [configuration['repository_root']] - .map { |r| { uri: r } } - .map { |r| augment_repository_root r } - .map { |r| augment_platform r } - .map { |r| augment_architecture r } - .map { |r| augment_path r }.flatten - end - - def repository_configuration?(configuration) - configuration['version'] && configuration['repository_root'] - end - def uris(configurations) uris = [] @@ -190,7 +146,7 @@ def uris(configurations) def get_from_cache(configuration, index_configuration, uris) @cache.get(index_configuration[:uri]) do |f| index = YAML.safe_load f - found_version = version(configuration, index) + found_version = Utils::VersionUtils.version(configuration, index) pin_version(configuration, found_version.to_s) if ENV['PINNED'].to_b if found_version.nil? @@ -205,12 +161,32 @@ def get_from_cache(configuration, index_configuration, uris) def pin_version(old_configuration, version) component_id = old_configuration['component_id'] sub_component_id = old_configuration['sub_component_id'] - rake_output_message "Pinning #{sub_component_id || component_id} version to #{version}" + if Utils::VersionUtils.openjdk_jre? old_configuration + rake_output_message "Pinning JRE #{sub_component_id || component_id} version to #{version}" + pin_jre(component_id, sub_component_id, version) + else + rake_output_message "Pinning #{sub_component_id || component_id} version to #{version}" + pin_component(component_id, sub_component_id, version) + end + end + + def pin_component(component_id, sub_component_id, version) configuration_to_update = JavaBuildpack::Util::ConfigurationUtils.load(component_id, false, true) update_configuration(configuration_to_update, version, sub_component_id) JavaBuildpack::Util::ConfigurationUtils.write(component_id, configuration_to_update) end + def pin_jre(component_id, sub_component_id, version) + # update configuration file, pin version & version lines + configuration_to_update = JavaBuildpack::Util::ConfigurationUtils.load(component_id, false, true) + update_configuration(configuration_to_update, version, sub_component_id) + configuration_to_update['jre']['version_lines'].each_with_index do |version_pattern, index| + configuration_to_update['jre']['version_lines'][index] = version \ + if Utils::VersionUtils.version_matches?(version_pattern, [version]) + end + JavaBuildpack::Util::ConfigurationUtils.write(component_id, configuration_to_update) + end + def update_configuration(config, version, sub_component) if sub_component.nil? config['version'] = version @@ -220,12 +196,5 @@ def update_configuration(config, version, sub_component) config.each_value { |v| update_configuration(v, version, sub_component) if v.is_a? Hash } end end - - def version(configuration, index) - JavaBuildpack::Repository::VersionResolver - .resolve(JavaBuildpack::Util::TokenizedVersion.new(configuration['version']), index.keys) - end - end - end diff --git a/rakelib/package.rb b/rakelib/package.rb index ebbac99291..5fffb464ac 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -19,6 +19,46 @@ module Package + def packaging + @pkgcfg = configuration('packaging') if @pkgcfg.nil? + @pkgcfg + end + + def configuration(id) + JavaBuildpack::Util::ConfigurationUtils.load(id, false, false) + end + + def configurations(component_id, configuration, sub_component_id = nil) + configurations = [] + + if repository_configuration?(configuration) + configuration['component_id'] = component_id + configuration['sub_component_id'] = sub_component_id if sub_component_id + + Utils::VersionUtils.java_version_lines(configuration, configurations) \ + if Utils::VersionUtils.openjdk_jre? configuration + + configurations << configuration + else + configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } + end + + configurations + end + + def index_configuration(configuration) + [configuration['repository_root']] + .map { |r| { uri: r } } + .map { |r| augment_repository_root r } + .map { |r| augment_platform r } + .map { |r| augment_architecture r } + .map { |r| augment_path r }.flatten + end + + def repository_configuration?(configuration) + configuration['version'] && configuration['repository_root'] + end + def self.offline '-offline' if BUILDPACK_VERSION.offline end diff --git a/rakelib/utils.rb b/rakelib/utils.rb new file mode 100644 index 0000000000..98a40fef8f --- /dev/null +++ b/rakelib/utils.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2022 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Utils + class VersionUtils + class << self + def version_wildcard?(version_pattern) + version_pattern.include? '+' + end + + def version(configuration, index) + matched_version(configuration['version'], index.keys) + end + + def matched_version(version_pattern, versions) + JavaBuildpack::Repository::VersionResolver + .resolve(JavaBuildpack::Util::TokenizedVersion.new(version_pattern), versions) + end + + def version_matches?(version_pattern, versions) + !matched_version(version_pattern, versions).nil? + end + + def openjdk_jre?(configuration) + configuration['component_id'].end_with?('_jre') && configuration['sub_component_id'].start_with?('jre') + end + + def java_version_lines(configuration, configurations) + configuration['version_lines'].each do |v| + next if version_line_matches?(configuration, v) + + c1 = configuration.clone + c1['sub_component_id'] = "jre-#{v.split('.')[0]}" + c1['version'] = v + configurations << c1 + end + end + + def version_line_matches?(configuration, v) + return true if v == configuration['version'] + return false if version_wildcard? v + + version_matches?(configuration['version'], [v]) + end + end + end +end diff --git a/rakelib/versions_task.rb b/rakelib/versions_task.rb index b0f21155b5..8869c181b1 100644 --- a/rakelib/versions_task.rb +++ b/rakelib/versions_task.rb @@ -24,6 +24,7 @@ require 'json' require 'rake/tasklib' require 'rakelib/package' +require 'rakelib/utils' require 'terminal-table' require 'yaml' @@ -36,6 +37,8 @@ class VersionsTask < Rake::TaskLib def initialize JavaBuildpack::Logging::LoggerFactory.instance.setup "#{BUILD_DIR}/" + @pkgcfg = nil + version_task namespace 'versions' do @@ -51,134 +54,9 @@ def initialize DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/.freeze - NAME_MAPPINGS = { - 'access_logging_support' => 'Tomcat Access Logging Support', - 'agent' => 'Java Memory Assistant Agent', - 'app_dynamics_agent' => 'AppDynamics Agent', - 'azure_application_insights_agent' => 'Azure Application Insights Agent', - 'clean_up' => 'Java Memory Assistant Clean Up', - 'client_certificate_mapper' => 'Client Certificate Mapper', - 'container_customizer' => 'Spring Boot Container Customizer', - 'container_security_provider' => 'Container Security Provider', - 'contrast_security_agent' => 'Contrast Security Agent', - 'datadog_javaagent' => 'Datadog APM Javaagent', - 'dynatrace_one_agent' => 'Dynatrace OneAgent', - 'elastic_apm_agent' => 'Elastic APM Agent', - 'geode_store' => 'Geode Tomcat Session Store', - 'google_stackdriver_debugger' => 'Google Stackdriver Debugger', - 'google_stackdriver_profiler' => 'Google Stackdriver Profiler', - 'groovy' => 'Groovy', - 'introscope_agent' => 'CA Introscope APM Framework', - 'jacoco_agent' => 'JaCoCo Agent', - 'jprofiler_profiler' => 'JProfiler Profiler', - 'jre' => 'OpenJDK JRE', - 'jre-11' => 'OpenJDK JRE 11', - 'jre-17' => 'OpenJDK JRE 17', - 'jrebel_agent' => 'JRebel Agent', - 'jvmkill_agent' => 'jvmkill Agent', - 'lifecycle_support' => 'Tomcat Lifecycle Support', - 'logging_support' => 'Tomcat Logging Support', - 'luna_security_provider' => 'Gemalto Luna Security Provider', - 'maria_db_jdbc' => 'MariaDB JDBC Driver', - 'memory_calculator' => 'Memory Calculator', - 'metric_writer' => 'Metric Writer', - 'new_relic_agent' => 'New Relic Agent', - 'postgresql_jdbc' => 'PostgreSQL JDBC Driver', - 'protect_app_security_provider' => 'Gemalto ProtectApp Security Provider', - 'redis_store' => 'Redis Session Store', - 'riverbed_appinternals_agent' => 'Riverbed Appinternals Agent', - 'sealights_agent' => 'SeaLights Agent', - 'sky_walking_agent' => 'SkyWalking', - 'spring_auto_reconfiguration' => 'Spring Auto-reconfiguration', - 'spring_boot_cli' => 'Spring Boot CLI', - 'takipi_agent' => 'Takipi Agent', - 'tomcat' => 'Tomcat', - 'your_kit_profiler' => 'YourKit Profiler' - }.freeze - - NOTE_LINKS = { - 'access_logging_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'agent' => { 'cve' => '', 'release' => '' }, - 'app_dynamics_agent' => { - 'cve' => '', - 'release' => '[Release Notes](https://docs.appdynamics.com/4.5.x/en/product-and-' \ - 'release-announcements/release-notes/language-agent-notes/java-agent-notes)' - }, - 'azure_application_insights_agent' => - { 'cve' => '', - 'release' => '[Release Notes](https://github.com/Microsoft/ApplicationInsights-Java/releases)' }, - 'clean_up' => { 'cve' => '', 'release' => '' }, - 'client_certificate_mapper' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'container_customizer' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'container_security_provider' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'contrast_security_agent' => - { 'cve' => '', - 'release' => '[Release Notes](https://docs.contrastsecurity.com/en/java-agent-release-notes.html)' }, - 'datadog_javaagent' => { 'cve' => '', - 'release' => '[Release Notes](https://github.com/DataDog/dd-trace-java/releases)' }, - 'dynatrace_one_agent' => - { 'cve' => '', - 'release' => '[Release Notes](https://www.dynatrace.com/support/help/whats-new/release-notes/#oneagent)' }, - 'elastic_apm_agent' => - { 'cve' => '', - 'release' => '[Release Notes](https://www.elastic.co/guide/en/apm/agent/java/current/release-notes.html)' }, - 'geode_store' => { 'cve' => '', 'release' => '' }, - 'google_stackdriver_debugger' => - { 'cve' => '', - 'release' => '[Release Notes](https://cloud.google.com/debugger/docs/release-notes)' }, - 'google_stackdriver_profiler' => - { 'cve' => '', - 'release' => '[Release Notes](https://cloud.google.com/profiler/docs/release-notes)' }, - 'groovy' => { 'cve' => '', 'release' => '[Release Notes](http://www.groovy-lang.org/releases.html)' }, - 'introscope_agent' => { 'cve' => '', 'release' => '' }, - 'jacoco_agent' => { 'cve' => '', 'release' => '[Release Notes](https://github.com/jacoco/jacoco/releases)' }, - 'jprofiler_profiler' => - { 'cve' => '', - 'release' => '[ChangeLog](https://www.ej-technologies.com/download/jprofiler/changelog.html)' }, - 'jre' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u342/)' }, - 'jre-11' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.16/)' }, - 'jre-17' => { 'cve' => '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)', - 'release' => '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.4/)' }, - 'jrebel_agent' => { 'cve' => '', 'release' => '[ChangeLog](https://www.jrebel.com/products/jrebel/changelog)' }, - 'jvmkill_agent' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'lifecycle_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'logging_support' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'luna_security_provider' => - { 'cve' => '', - 'release' => - '[Release Notes](https://www.thalesdocs.com/gphsm/luna/7/docs/network/Content/CRN/Luna/CRN_Luna.htm)' }, - 'maria_db_jdbc' => - { 'cve' => '', - 'release' => '[Release Notes](https://mariadb.com/kb/en/mariadb-connector-j-274-release-notes/)' }, - 'memory_calculator' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'metric_writer' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'new_relic_agent' => - { 'cve' => '', - 'release' => - '[Release Notes](https://docs.newrelic.com/docs/release-notes/agent-release-notes/java-release-notes/)' }, - 'postgresql_jdbc' => { 'cve' => '', - 'release' => '[ChangeLog](https://jdbc.postgresql.org/documentation/changelog.html)' }, - 'protect_app_security_provider' => { 'cve' => '', 'release' => '' }, - 'redis_store' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'riverbed_appinternals_agent' => { 'cve' => '', 'release' => '' }, - 'sealights_agent' => { 'cve' => '', 'release' => '' }, - 'sky_walking_agent' => { 'cve' => '', - 'release' => '[ChangeLog](https://github.com/apache/skywalking/tree/master/changes)' }, - 'spring_auto_reconfiguration' => { 'cve' => 'Included inline above', 'release' => 'Included inline above' }, - 'spring_boot_cli' => { 'cve' => '', 'release' => '' }, - 'takipi_agent' => { 'cve' => '', 'release' => '[Release Notes](https://doc.overops.com/docs/whats-new)' }, - 'tomcat' => { 'cve' => '[Security](https://tomcat.apache.org/security-9.html)', - 'release' => '[ChangeLog](https://tomcat.apache.org/tomcat-9.0-doc/changelog.html)' }, - 'your_kit_profiler' => { 'cve' => '', - 'release' => '[Release Notes](https://www.yourkit.com/download/yjp_2022_3_builds.jsp)' } - }.freeze - PLATFORM_PATTERN = /\{platform\}/.freeze - private_constant :ARCHITECTURE_PATTERN, :DEFAULT_REPOSITORY_ROOT_PATTERN, :NAME_MAPPINGS, - :PLATFORM_PATTERN, :NOTE_LINKS + private_constant :ARCHITECTURE_PATTERN, :DEFAULT_REPOSITORY_ROOT_PATTERN, :PLATFORM_PATTERN def augment(raw, key, pattern, candidates, &block) if raw.respond_to? :at @@ -227,40 +105,6 @@ def component_ids configuration('components').values.flatten.map { |component| component.split('::').last.snake_case } end - def configuration(id) - JavaBuildpack::Util::ConfigurationUtils.load(id, false, false) - end - - def configurations(component_id, configuration, sub_component_id = nil) - configurations = [] - - if repository_configuration?(configuration) - configuration['component_id'] = component_id - configuration['sub_component_id'] = sub_component_id if sub_component_id - - if component_id == 'open_jdk_jre' && sub_component_id == 'jre' - c1 = configuration.clone - c1['sub_component_id'] = 'jre-11' - c1['version'] = '11.+' - - configurations << c1 - end - - if component_id == 'open_jdk_jre' && sub_component_id == 'jre' - c1 = configuration.clone - c1['sub_component_id'] = 'jre-17' - c1['version'] = '17.+' - - configurations << c1 - end - configurations << configuration - else - configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } - end - - configurations - end - def default_repository_root configuration('repository')['default_repository_root'].chomp('/') end @@ -268,7 +112,7 @@ def default_repository_root def get_from_cache(cache, configuration, index_configuration) cache.get(index_configuration[:uri]) do |f| index = YAML.safe_load f - found_version = version(configuration, index) + found_version = Utils::VersionUtils.version(configuration, index) if found_version.nil? raise "Unable to resolve version '#{configuration['version']}' for platform " \ @@ -300,7 +144,7 @@ def map_config_to_dependency(cache, configuration, dependency_versions) index_configuration(configuration).each do |index_configuration| version, uri = get_from_cache(cache, configuration, index_configuration) - name = NAME_MAPPINGS[id] + name = packaging[id]['name'] raise "Unable to resolve name for '#{id}'" unless name dependency_versions << { @@ -308,30 +152,12 @@ def map_config_to_dependency(cache, configuration, dependency_versions) 'name' => name, 'uri' => uri, 'version' => version, - 'cve_link' => NOTE_LINKS[id]['cve'], - 'release_notes_link' => NOTE_LINKS[id]['release'] + 'cve_link' => packaging[id]['cve_notes'] || '', + 'release_notes_link' => packaging[id]['release_notes'] || '' } end end - def index_configuration(configuration) - [configuration['repository_root']] - .map { |r| { uri: r } } - .map { |r| augment_repository_root r } - .map { |r| augment_platform r } - .map { |r| augment_architecture r } - .map { |r| augment_path r }.flatten - end - - def repository_configuration?(configuration) - configuration['version'] && configuration['repository_root'] - end - - def version(configuration, index) - JavaBuildpack::Repository::VersionResolver - .resolve(JavaBuildpack::Util::TokenizedVersion.new(configuration['version']), index.keys) - end - def version_task desc 'Display the versions of buildpack dependencies in human readable form' task versions: [] do diff --git a/spec/java_buildpack/util/configuration_utils_spec.rb b/spec/java_buildpack/util/configuration_utils_spec.rb index fe5911bf0e..9ebd64ada7 100644 --- a/spec/java_buildpack/util/configuration_utils_spec.rb +++ b/spec/java_buildpack/util/configuration_utils_spec.rb @@ -99,6 +99,66 @@ end + context do + + let(:environment) do + { 'JBP_DEFAULT_TEST' => '{bar: {alpha: {one: 3, two: {one: 3}}, bravo: newValue}, foo: lion}' } + end + + it 'overlays operator default matching environment variables' do + + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 3, 'two' => 'dog' } }, + 'version' => '1.7.1') + end + + end + + context do + + let(:environment) do + { 'JBP_DEFAULT_TEST' => '{version: 1.8.+}' } + end + + it 'overlays operator default config' do + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '1.8.+') + end + + end + + context do + + let(:environment) do + { 'JBP_DEFAULT_TEST' => '{version: 11.+}', + 'JBP_CONFIG_TEST' => '{version: 17.+}' } + end + + it 'overlays operator default config and environment variable config' do + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 'cat', 'two' => 'dog' } }, + 'version' => '17.+') + end + + end + + context do + + let(:environment) do + { 'JBP_DEFAULT_TEST' => '{bar: {alpha: {one: 3, two: {one: 3}}, bravo: newValue}}', + 'JBP_CONFIG_TEST' => '{bar: {alpha: {one: 9, two: {one: 3}}, bravo: newValue}}' } + end + + it 'overlays operator default matching and environment variables' do + + expect(described_class.load('test')).to eq('foo' => { 'one' => '1', 'two' => 2 }, + 'bar' => { 'alpha' => { 'one' => 9, 'two' => 'dog' } }, + 'version' => '1.7.1') + end + + end + context do let(:environment) do From 4dedaf4724dfb8c0f8e30c52571b20acf75b30e3 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Thu, 28 Jul 2022 16:58:49 -0400 Subject: [PATCH 690/812] Fixes typo in README regarding `JBP_DEFAULT` (#962) Signed-off-by: Daniel Mikusa --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8f527237c1..4f29fe943f 100644 --- a/README.md +++ b/README.md @@ -42,13 +42,13 @@ $ cf set-staging-environment-variable-group '{"JBP_DEFAULT_OPEN_JDK_JRE":"{jre: 2. To change the default repository root across all applications on a foundation. Be careful to ensure that your JSON is properly escaped. ```bash -$ cf set-staging-environment-variable-group '{"JBP_CONFIG_REPOSITORY": "{default_repository_root: \"http://repo.example.io\" }"}' +$ cf set-staging-environment-variable-group '{"JBP_DEFAULT_REPOSITORY": "{default_repository_root: \"http://repo.example.io\" }"}' ``` 3. To change the default JVM vendor across all applications on a foundation. Be careful to ensure that your JSON is properly escaped. ```bash -$ cf set-staging-environment-variable-group '{"JBP_CONFIG_COMPONENTS": "{jres: [\"JavaBuildpack::Jre::ZuluJRE\"]}"}' +$ cf set-staging-environment-variable-group '{"JBP_DEFAULT_COMPONENTS": "{jres: [\"JavaBuildpack::Jre::ZuluJRE\"]}"}' ``` ### Application Developer From 1c56fe27b176b36cb0aa50c23820a6fb287cd1ad Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Mon, 12 Sep 2022 13:43:48 +0100 Subject: [PATCH 691/812] Disables the SAR library by default --- config/spring_auto_reconfiguration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/spring_auto_reconfiguration.yml b/config/spring_auto_reconfiguration.yml index 14e976bff7..b0be97c8b3 100644 --- a/config/spring_auto_reconfiguration.yml +++ b/config/spring_auto_reconfiguration.yml @@ -19,4 +19,4 @@ --- version: 2.+ repository_root: "{default.repository.root}/auto-reconfiguration" -enabled: true +enabled: false From f476e25149533c5e9414a62ad59e9bbe0507af44 Mon Sep 17 00:00:00 2001 From: Alon Weiss Date: Wed, 14 Sep 2022 00:00:03 +0300 Subject: [PATCH 692/812] Accept lab_id, proxy and enable_upgrade from user provisioned service +Explicitly set agent automatic upgrade flag --- docs/framework-sealights_agent.md | 6 +++ .../framework/sealights_agent.rb | 23 +++++++++-- .../framework/sealights_agent_spec.rb | 41 ++++++++++++++++++- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/docs/framework-sealights_agent.md b/docs/framework-sealights_agent.md index 7b3cf524d4..235254b8a9 100644 --- a/docs/framework-sealights_agent.md +++ b/docs/framework-sealights_agent.md @@ -19,6 +19,10 @@ The credential payload can contain the following entries. | Name | Description | ---- | ----------- | `token` | A Sealights Agent token +| `proxy` | Specify a HTTP proxy used to communicate with the Sealights backend. Required when a corporate network prohibits communication to cloud services. The default is to have no proxy configured. This does not inherit from `http_proxy`/`https_proxy` or `http.proxyHost/https.proxyHost`, you must set this specifically if a proxy is needed. +| `lab_id` | Specify a Sealights [Lab ID][] + +All fields above except the agent token may be also specified in the [Configuration Section](#configuration) below. ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. @@ -33,6 +37,8 @@ The framework can be configured by modifying the [`config/sealights_agent.yml`][ | `auto_upgrade` | Enable/disable agent auto-upgrade. Off by default | `version` | The version of Auto-reconfiguration to use. Candidate versions can be found in [this listing][]. If auto_upgrade is turned on, a different version may be downloaded and used at runtime +Configuration settings will take precedence over the ones specified in the [User-Provided Service](#user-provided-service), if those are defined. + ## Troubleshooting and Support For additional documentation and support, visit the official [Sealights Java agents documentation] page diff --git a/lib/java_buildpack/framework/sealights_agent.rb b/lib/java_buildpack/framework/sealights_agent.rb index c40e034fc9..3e6331a7fe 100644 --- a/lib/java_buildpack/framework/sealights_agent.rb +++ b/lib/java_buildpack/framework/sealights_agent.rb @@ -43,10 +43,18 @@ def release credentials = @application.services.find_service(FILTER, TOKEN)['credentials'] @droplet.java_opts.add_system_property('sl.token', Shellwords.escape(credentials[TOKEN])) @droplet.java_opts.add_system_property('sl.tags', 'pivotal_cloud_foundry') - add_system_property 'sl.enableUpgrade', ENABLE_UPGRADE + + # add sl.enableUpgrade system property + @droplet.java_opts.add_system_property('sl.enableUpgrade', @configuration[ENABLE_UPGRADE] ? 'true' : 'false') + + # add sl.proxy system property if defined (either in config or user provisioned service) + add_system_property_from_cfg_or_svc credentials, 'sl.proxy', PROXY + + # add sl.labId system property if defined (either in config or user provisioned service) + add_system_property_from_cfg_or_svc credentials, 'sl.labId', LAB_ID + + # add build session if defined in config add_system_property 'sl.buildSessionId', BUILD_SESSION_ID - add_system_property 'sl.proxy', PROXY - add_system_property 'sl.labId', LAB_ID end # wrapper for setting system properties on the droplet from configuration keys @@ -56,6 +64,15 @@ def add_system_property(system_property, config_key) @droplet.java_opts.add_system_property(system_property, Shellwords.escape(@configuration[config_key])) end + # add a system property based on either plugin configuration (which takes precedence) or user provisioned service + def add_system_property_from_cfg_or_svc(svc, system_property, config_key) + if @configuration.key?(config_key) + @droplet.java_opts.add_system_property(system_property, Shellwords.escape(@configuration[config_key])) + elsif svc.key?(config_key) + @droplet.java_opts.add_system_property(system_property, Shellwords.escape(svc[config_key])) + end + end + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? @application.services.one_service? FILTER, TOKEN diff --git a/spec/java_buildpack/framework/sealights_agent_spec.rb b/spec/java_buildpack/framework/sealights_agent_spec.rb index b85ce66f56..a6d5fb8870 100644 --- a/spec/java_buildpack/framework/sealights_agent_spec.rb +++ b/spec/java_buildpack/framework/sealights_agent_spec.rb @@ -106,12 +106,49 @@ expect(java_opts).not_to include(/proxy/) end - it 'does not specify JAVA_OPTS sl.enableUpgrade if one was not specified' do + it 'sets JAVA_OPTS sl.enableUpgrade to false by default' do component.release - expect(java_opts).not_to include(/enableUpgrade/) + expect(java_opts).to include('-Dsl.enableUpgrade=false') end + end + + context do + let(:credentials) { { 'token' => 'my_token', 'proxy' => 'my_proxy', 'lab_id' => 'my_lab' } } + let(:configuration) { {} } + + it 'updates JAVA_OPTS sl.labId from the user provisioned service' do + component.release + + expect(java_opts).to include("-Dsl.labId=#{credentials['lab_id']}") + end + + it 'updates JAVA_OPTS sl.proxy from the user provisioned service' do + component.release + + expect(java_opts).to include("-Dsl.proxy=#{credentials['proxy']}") + end + end + context do + let(:credentials) { { 'token' => 'my_token', 'proxy' => 'my_proxy', 'lab_id' => 'my_lab' } } + + let(:configuration) do + { 'proxy' => '127.0.0.1:8888', + 'lab_id' => 'lab1' } + end + + it 'updates JAVA_OPTS sl.labId from config (and not user provisioned service)' do + component.release + + expect(java_opts).to include("-Dsl.labId=#{configuration['lab_id']}") + end + + it 'updates JAVA_OPTS sl.proxy from config (and not user provisioned service)' do + component.release + + expect(java_opts).to include("-Dsl.proxy=#{configuration['proxy']}") + end end end From 7c46b1d316b963b3bd5f55ca6b52657866ca4ed1 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Mon, 19 Sep 2022 15:57:04 -0700 Subject: [PATCH 693/812] Introduce the splunk-otel-java-agent framework. This framework will wire up the splunk distribution of opentelemetry java for auto-instrumentation and direct ingest. It leverages VCAP_SERVICES and the existence of a service binding with a specific name (splunk-o11y). Signed-off-by: Jason Plumb jplumb@splunk.com Resolves issue #825 --- config/components.yml | 1 + config/splunk_otel_java_agent.yml | 21 +++++ docs/framework-splunk_otel_java_agent.md | 51 ++++++++++++ .../framework/splunk_otel_java_agent.rb | 58 ++++++++++++++ spec/fixtures/stub-splunk-otel-javaagent.jar | Bin 0 -> 341 bytes .../framework/splunk_otel_java_agent_spec.rb | 74 ++++++++++++++++++ 6 files changed, 205 insertions(+) create mode 100644 config/splunk_otel_java_agent.yml create mode 100644 docs/framework-splunk_otel_java_agent.md create mode 100644 lib/java_buildpack/framework/splunk_otel_java_agent.rb create mode 100644 spec/fixtures/stub-splunk-otel-javaagent.jar create mode 100644 spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb diff --git a/config/components.yml b/config/components.yml index 9011950635..933bf1a413 100644 --- a/config/components.yml +++ b/config/components.yml @@ -71,6 +71,7 @@ frameworks: - "JavaBuildpack::Framework::SealightsAgent" - "JavaBuildpack::Framework::SeekerSecurityProvider" - "JavaBuildpack::Framework::SpringAutoReconfiguration" + - "JavaBuildpack::Framework::SplunkOtelJavaAgent" - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::SkyWalkingAgent" - "JavaBuildpack::Framework::YourKitProfiler" diff --git a/config/splunk_otel_java_agent.yml b/config/splunk_otel_java_agent.yml new file mode 100644 index 0000000000..7a3824cf67 --- /dev/null +++ b/config/splunk_otel_java_agent.yml @@ -0,0 +1,21 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Splunk Distribution of OpenTelemetry Java Instrumentation +# See https://github.com/signalfx/splunk-otel-java for more information +--- +version: + +repository_root: https://raw.githubusercontent.com/signalfx/splunk-otel-java/main/deployments/cloudfoundry/ + \ No newline at end of file diff --git a/docs/framework-splunk_otel_java_agent.md b/docs/framework-splunk_otel_java_agent.md new file mode 100644 index 0000000000..5724c8aec1 --- /dev/null +++ b/docs/framework-splunk_otel_java_agent.md @@ -0,0 +1,51 @@ +# Splunk Distribution of OpenTelemetry Java Instrumentation + +The Splunk OpenTelemetry Java Agent buildpack framework will cause an application to be automatically instrumented +with the [Splunk distribution of OpenTelemetry Java Instrumentation](https://github.com/signalfx/splunk-otel-java). + +Trace data will be sent directly to Splunk Observability Cloud. + +* **Detection criteria**: Existence of a bound service with the name `splunk-o11y`. +* **Tags**: `splunk-otel-java-agent=` to control which version of the instrumentation agent is used. + * Default = latest available version + +## User-Provided Service + +Users are currently expected to provide their own "custom user provided service" (cups) +instance and bind it to their application. The service MUST be named `splunk-o11y`. + +For example, to create a service named `splunk-o11y` that represents Observability Cloud +realm `us0` and represents a user environment named `cf-demo`, you could use the following +commands: + +``` +$ cf cups splunk-o11y -p \ + '{"splunk.realm": "us0", "splunk.access.token": "", "otel.resource.attributes": "deployment.environment=cf-demo"}' +$ cf bind-service myApp splunk-o11y +$ cf restage myApp +``` + +The `credential` field of the service should provide these entries: + +| Name | Required? | Description +|------------------------|-----------| ----------- +| `splunk.access.token` | Yes | The Splunk [org access token](https://docs.splunk.com/observability/admin/authentication-tokens/org-tokens.html). +| `splunk.realm` | Yes | The Splunk realm where data will be sent. This is commonly `us0` or `eu0` etc. +| `otel.*` or `splunk.*` | Optional | All additional credentials starting with these prefixes will be appended to the application's JVM arguments as system properties. + +### Choosing a version + +Most users should skip this and simply use the latest version of the agent available (the default). +To override the default and choose a specific version, you can use the `JBP_CONFIG_*` mechanism +and set the `JBP_CONFIG_SPLUNK_OTEL_JAVA_AGENT` environment variable for your application. + +For example, to use version 1.16.0 of the Splunk OpenTelemetry Java Instrumentation, you +could run: +``` +$ cf set-env testapp JBP_CONFIG_SPLUNK_OTEL_JAVA_AGENT '{version: 1.16.0}' +``` + +# Additional Resources + +* [Splunk Observability](https://www.splunk.com/en_us/products/observability.html) +* [Splunk Distribution of OpenTelemetry Java](https://github.com/signalfx/splunk-otel-java) on GitHub diff --git a/lib/java_buildpack/framework/splunk_otel_java_agent.rb b/lib/java_buildpack/framework/splunk_otel_java_agent.rb new file mode 100644 index 0000000000..bb18e59913 --- /dev/null +++ b/lib/java_buildpack/framework/splunk_otel_java_agent.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Main class for adding the Splunk OpenTelemetry instrumentation agent + class SplunkOtelJavaAgent < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + java_opts = @droplet.java_opts + java_opts.add_javaagent(@droplet.sandbox + jar_name) + + credentials = @application.services.find_service(REQUIRED_SERVICE_NAME_FILTER)['credentials'] + # Add all otel.* and splunk.* credentials from the service bind as jvm system properties + credentials&.each do |key, value| + java_opts.add_system_property(key, value) if key.start_with?('splunk.') || key.start_with?('otel.') + end + + app_name = @application.details['application_name'] + java_opts.add_system_property('otel.service.name', app_name) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? REQUIRED_SERVICE_NAME_FILTER + end + + REQUIRED_SERVICE_NAME_FILTER = /^splunk-o11y$/.freeze + + end + end +end diff --git a/spec/fixtures/stub-splunk-otel-javaagent.jar b/spec/fixtures/stub-splunk-otel-javaagent.jar new file mode 100644 index 0000000000000000000000000000000000000000..0878c3ccb50e0696f38ae356e9854c75199158f3 GIT binary patch literal 341 zcmWIWW@Zs#;Nak3$ZLM$#DD}i8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1gx0>v$BCyF#%yMkUj+BFaQAGLPY%l literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb b/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb new file mode 100644 index 0000000000..476f78ad52 --- /dev/null +++ b/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/splunk_otel_java_agent' +require 'java_buildpack/util/tokenized_version' + +describe JavaBuildpack::Framework::SplunkOtelJavaAgent do + include_context 'with component help' + + let(:configuration) { { 'version' => '1.16.0' } } + let(:vcap_application) { { 'application_name' => 'GreatServiceTM' } } + + it 'does not detect without splunk-o11y service bind' do + expect(component.detect).to be_nil + end + + context 'when detected' do + + before do + allow(services).to receive(:one_service?).with(/^splunk-o11y$/).and_return(true) + end + + it 'detects with splunk-otel-java' do + expect(component.detect).to eq("splunk-otel-java-agent=#{version}") + end + + it 'downloads the splunk otel javaagent jar', cache_fixture: 'stub-splunk-otel-javaagent.jar' do + + component.compile + + expect(sandbox + "splunk_otel_java_agent-#{version}.jar").to exist + end + + it 'updates JAVA_OPTS' do + allow(services).to receive(:find_service).and_return('credentials' => { 'splunk.access.token' => 'sekret', + 'ignored' => 'not used', + 'otel.foo' => 'bar' }) + component.release + + expect(java_opts).to include( + "-javaagent:$PWD/.java-buildpack/splunk_otel_java_agent/splunk_otel_java_agent-#{version}.jar" + ) + expect(java_opts).to include('-Dsplunk.access.token=sekret') + expect(java_opts).to include('-Dotel.foo=bar') + end + + it 'sets the service name from the application name' do + allow(services).to receive(:find_service).and_return('credentials' => { 'splunk.access.token' => 'sekret' }) + # allow(details).to be( { 'application_name' => 'dick' }) + + component.release + + expect(java_opts).to include('-Dotel.service.name=GreatServiceTM') + end + + end + +end From 6f9edba2dec93f5e9ec184106d0e97150116e8b5 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Tue, 20 Sep 2022 07:31:27 +0100 Subject: [PATCH 694/812] update release note --- config/packaging.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/packaging.yml b/config/packaging.yml index 31bb350dd0..de04178b0d 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -93,7 +93,7 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u342/)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u345/)' jre-11: name: OpenJDK JRE 11 From c8f94c58719e8cc2c28ed81ba42673bdd16b973a Mon Sep 17 00:00:00 2001 From: Frank Gasparovic Date: Tue, 27 Sep 2022 10:29:07 -0700 Subject: [PATCH 695/812] Updated Contrast agent version --- config/contrast_security_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index 51d0495a14..d7615bc680 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -15,5 +15,5 @@ # Configuration for the ContrastSecurity framework --- -version: 3.+ +version: 4.+ repository_root: https://download.run.pivotal.io/contrast-security From 52a6183baa0444b5d930e37bb8a23efd5ae9e3d3 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Wed, 14 Sep 2022 10:53:16 -0700 Subject: [PATCH 696/812] Use consistent doc table format --- docs/framework-splunk_otel_java_agent.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/framework-splunk_otel_java_agent.md b/docs/framework-splunk_otel_java_agent.md index 5724c8aec1..0ba30e97d5 100644 --- a/docs/framework-splunk_otel_java_agent.md +++ b/docs/framework-splunk_otel_java_agent.md @@ -5,14 +5,23 @@ with the [Splunk distribution of OpenTelemetry Java Instrumentation](https://git Trace data will be sent directly to Splunk Observability Cloud. -* **Detection criteria**: Existence of a bound service with the name `splunk-o11y`. -* **Tags**: `splunk-otel-java-agent=` to control which version of the instrumentation agent is used. - * Default = latest available version + + + + + + + + + +
Detection CriterionExistence of a bound service containing the string splunk-o11y
Tagssplunk-otel-java-agent=<version>
+ +Tags are printed to standard output by the buildpack detect script ## User-Provided Service Users are currently expected to provide their own "custom user provided service" (cups) -instance and bind it to their application. The service MUST be named `splunk-o11y`. +instance and bind it to their application. The service MUST contain the string `splunk-o11y`. For example, to create a service named `splunk-o11y` that represents Observability Cloud realm `us0` and represents a user environment named `cf-demo`, you could use the following From 8e0e951cf1d13e663d22dc445e5e48392aa6f584 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Thu, 29 Sep 2022 13:07:15 -0700 Subject: [PATCH 697/812] relax to substring match --- lib/java_buildpack/framework/splunk_otel_java_agent.rb | 2 +- spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/splunk_otel_java_agent.rb b/lib/java_buildpack/framework/splunk_otel_java_agent.rb index bb18e59913..160605eb7f 100644 --- a/lib/java_buildpack/framework/splunk_otel_java_agent.rb +++ b/lib/java_buildpack/framework/splunk_otel_java_agent.rb @@ -51,7 +51,7 @@ def supports? @application.services.one_service? REQUIRED_SERVICE_NAME_FILTER end - REQUIRED_SERVICE_NAME_FILTER = /^splunk-o11y$/.freeze + REQUIRED_SERVICE_NAME_FILTER = /splunk-o11y/.freeze end end diff --git a/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb b/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb index 476f78ad52..96797b96f5 100644 --- a/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb +++ b/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb @@ -33,7 +33,7 @@ context 'when detected' do before do - allow(services).to receive(:one_service?).with(/^splunk-o11y$/).and_return(true) + allow(services).to receive(:one_service?).with(/splunk-o11y/).and_return(true) end it 'detects with splunk-otel-java' do From 71b5948c7c0870d86d153fa5856b37dd9b8775b8 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Thu, 29 Sep 2022 14:02:02 -0700 Subject: [PATCH 698/812] only set otel.service.name from application_name if not set in credentials --- lib/java_buildpack/framework/splunk_otel_java_agent.rb | 4 ++++ .../framework/splunk_otel_java_agent_spec.rb | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/splunk_otel_java_agent.rb b/lib/java_buildpack/framework/splunk_otel_java_agent.rb index 160605eb7f..f3361a869d 100644 --- a/lib/java_buildpack/framework/splunk_otel_java_agent.rb +++ b/lib/java_buildpack/framework/splunk_otel_java_agent.rb @@ -40,6 +40,9 @@ def release java_opts.add_system_property(key, value) if key.start_with?('splunk.') || key.start_with?('otel.') end + # Set the otel.service.name to the application_name if not specified in credentials + return if credentials.key? 'otel.service.name' + app_name = @application.details['application_name'] java_opts.add_system_property('otel.service.name', app_name) end @@ -51,6 +54,7 @@ def supports? @application.services.one_service? REQUIRED_SERVICE_NAME_FILTER end + # bound service must contain the string `splunk-o11y` REQUIRED_SERVICE_NAME_FILTER = /splunk-o11y/.freeze end diff --git a/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb b/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb index 96797b96f5..eb75ada8e5 100644 --- a/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb +++ b/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb @@ -62,13 +62,21 @@ it 'sets the service name from the application name' do allow(services).to receive(:find_service).and_return('credentials' => { 'splunk.access.token' => 'sekret' }) - # allow(details).to be( { 'application_name' => 'dick' }) component.release expect(java_opts).to include('-Dotel.service.name=GreatServiceTM') end + it 'prefers credentials over application_name for service name' do + creds = { 'credentials' => { 'otel.service.name' => 'sweet', 'splunk.access.token' => 'sekret' } } + allow(services).to receive(:find_service).and_return(creds) + + component.release + + expect(java_opts).to include('-Dotel.service.name=sweet') + end + end end From 81b261e1a96ac22259c0e4a75c5abc639a164fdb Mon Sep 17 00:00:00 2001 From: Chris Clark Date: Fri, 30 Sep 2022 13:45:30 -0400 Subject: [PATCH 699/812] Update CONTRIBUTING.md (#973) Updating CLA instructions --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3a36fc75bd..d1c35a9bc9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,9 @@ If you're considering anything more than correcting a typo or fixing a minor bug [vcap-dev]: https://groups.google.com/a/cloudfoundry.org/forum/#!forum/vcap-dev ## Sign the Contributor License Agreement -Please open an issue in the [GitHub issue tracker][] to receive instructions on how to fill out the Contributor License Agreement. +If you are not yet covered under a Corporate CLA or Individual CLA, you'll be prompted to sign or be approved by your company when you put in your first Pull Request. Please follow the prompts in the EasyCLA check within that Pull Request. For additional assistance please [open a ticket here][]. + +[open a ticket here]: https://jira.linuxfoundation.org/servicedesk/customer/portal/4 ## Use short branch names Branches used when submitting pull requests should preferably using succinct, lower-case, dash (-) delimited names, such as 'fix-warnings', 'fix-typo', etc. In [fork-and-edit][] cases, the GitHub default 'patch-1' is fine as well. This is important, because branch names show up in the merge commits that result from accepting pull requests, and should be as expressive and concise as possible. From e2be18ad341084a3eae0a7192c063de6abe8ff2b Mon Sep 17 00:00:00 2001 From: Rene Bamberger Date: Mon, 3 Oct 2022 14:45:03 +0200 Subject: [PATCH 700/812] Handle Dynatrace API Token in the sanitizer --- lib/java_buildpack/util/sanitizer.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index 29253e07fd..c2dbac667f 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -25,6 +25,7 @@ def sanitize_uri rich_uri = URI(self) rich_uri.user = nil rich_uri.password = nil + rich_uri.query = rich_uri.query&.gsub(/(Api-Token=dt\w*\.\w*)\.\w*/, '\1.REDACTED') rich_uri.to_s end From 7b30f8415676ccba5f85782343303b765ca7c61e Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 3 Nov 2022 17:36:44 +0000 Subject: [PATCH 701/812] Re-enables auto-reconfig by default --- config/spring_auto_reconfiguration.yml | 2 +- lib/java_buildpack/framework/spring_auto_reconfiguration.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/spring_auto_reconfiguration.yml b/config/spring_auto_reconfiguration.yml index b0be97c8b3..14e976bff7 100644 --- a/config/spring_auto_reconfiguration.yml +++ b/config/spring_auto_reconfiguration.yml @@ -19,4 +19,4 @@ --- version: 2.+ repository_root: "{default.repository.root}/auto-reconfiguration" -enabled: false +enabled: true diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 92fc27ff07..09537efbfc 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -71,7 +71,7 @@ def log_warning_scc_manual @logger.warn do 'ATTENTION: The Spring Cloud Connectors library is present in your application. This library ' \ 'has been in maintenance mode since July 2019 and will stop receiving all updates after ' \ - 'Dec 2022.' + 'Aug 2023.' end @logger.warn do 'Please migrate to java-cfenv immediately. See https://via.vmw.com/EiBW for migration instructions.' \ @@ -87,8 +87,8 @@ def log_warning_sar_scc_auto @logger.warn do 'If you are not using these libraries, set `JBP_CONFIG_SPRING_AUTO_RECONFIGURATION=\'{enabled: false}\'` ' \ 'to disable their installation and clear this warning message. The buildpack will switch its default ' \ - 'to disable by default after Aug 2022. Spring Auto Reconfiguration and its shaded Spring Cloud ' \ - 'Connectors will be removed from the buildpack after Dec 2022.' + 'to disable by default after April 2023. Spring Auto Reconfiguration and its shaded Spring Cloud ' \ + 'Connectors will be removed from the buildpack after Aug 2023.' end @logger.warn do 'If you are using these libraries, please migrate to java-cfenv immediately. ' \ From fc836823f222662ae25a565701e2f81e70977e3b Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Sun, 6 Nov 2022 20:02:58 +0000 Subject: [PATCH 702/812] Set new date for SAR deprecation --- lib/java_buildpack/framework/spring_auto_reconfiguration.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 09537efbfc..80b20ca027 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -71,7 +71,7 @@ def log_warning_scc_manual @logger.warn do 'ATTENTION: The Spring Cloud Connectors library is present in your application. This library ' \ 'has been in maintenance mode since July 2019 and will stop receiving all updates after ' \ - 'Aug 2023.' + 'Mar 2024.' end @logger.warn do 'Please migrate to java-cfenv immediately. See https://via.vmw.com/EiBW for migration instructions.' \ @@ -87,8 +87,8 @@ def log_warning_sar_scc_auto @logger.warn do 'If you are not using these libraries, set `JBP_CONFIG_SPRING_AUTO_RECONFIGURATION=\'{enabled: false}\'` ' \ 'to disable their installation and clear this warning message. The buildpack will switch its default ' \ - 'to disable by default after April 2023. Spring Auto Reconfiguration and its shaded Spring Cloud ' \ - 'Connectors will be removed from the buildpack after Aug 2023.' + 'to disable by default after March 2023. Spring Auto Reconfiguration and its shaded Spring Cloud ' \ + 'Connectors will be removed from the buildpack after March 2024.' end @logger.warn do 'If you are using these libraries, please migrate to java-cfenv immediately. ' \ From 96b6de0a5b779a56d7163098b1592a0e8f2b8587 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Mon, 7 Nov 2022 17:07:59 +0000 Subject: [PATCH 703/812] Added Java Release note updates --- config/packaging.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index de04178b0d..74eaea3692 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -92,18 +92,18 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u345/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u352/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.16/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.17/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.4/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.5/)' jrebel_agent: name: JRebel Agent From f6e9b5f64cb1f11b1bfa306ba60ca87b3a58cc2b Mon Sep 17 00:00:00 2001 From: Stefan Mayr Date: Sun, 13 Nov 2022 08:12:31 +0100 Subject: [PATCH 704/812] Add connection string for Azure Application Insights Agent 3.x Add connection string to the Azure Application Insights Agent tests Add docs for Azure Application Insights Agent --- README.md | 1 + ...mework-azure_application_insights_agent.md | 33 +++++++++++++++++++ .../azure_application_insights_agent.rb | 19 +++++++---- .../azure_application_insights_agent_spec.rb | 8 +++-- 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 docs/framework-azure_application_insights_agent.md diff --git a/README.md b/README.md index 4f29fe943f..4095ef15fc 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ The buildpack supports extension through the use of Git repository forking. The * Standard Frameworks * [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration)) * [AspectJ Weaver Agent](docs/framework-aspectj_weaver_agent.md) ([Configuration](docs/framework-aspectj_weaver_agent.md#configuration)) + * [Azure Application Insights Agent](docs/framework-azure_application_insights_agent.md) ([Configuration](docs/framework-azure_application_insights_agent.md#configuration)) * [Checkmarx IAST Agent](docs/framework-checkmarx_iast_agent.md) ([Configuration](docs/framework-checkmarx_iast_agent.md#configuration)) * [Client Certificate Mapper](docs/framework-client_certificate_mapper.md) ([Configuration](docs/framework-client_certificate_mapper.md#configuration)) * [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration)) diff --git a/docs/framework-azure_application_insights_agent.md b/docs/framework-azure_application_insights_agent.md new file mode 100644 index 0000000000..ec78d2c921 --- /dev/null +++ b/docs/framework-azure_application_insights_agent.md @@ -0,0 +1,33 @@ +# Azure Application Insights Agent Framework +The Azure Application Insights Agent Framework causes an application to be automatically configured to work with a bound [Azure Application Insights Service][]. **Note:** This framework is disabled by default. + + + + + + + + + +
Detection CriterionExistence of a single bound Azure Application Insights service. +
    +
  • Existence of a Azure Application Insights service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has azure-application-insights as a substring with at least `connection_string` or `instrumentation_key` set as credentials.
  • +
+
Tagsazure-application-insights=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +Users must provide their own Azure Application Insights service. A user-provided Azure Application Insights service must have a name or tag with `azure-application-insights` in it so that the Azure Application Insights Agent Framework Framework will automatically configure the application to work with the service. + +The credential payload of the service has to contain one of the following entries: + +| Name | Description +| ---- | ----------- +| `connection_string` | With agent version 3.x the connection string is required. You can find your connection string in your Application Insights resource. +| `instrumentation_key` | With agent version 2.x the instrumentation key is required. With version 3.x this configuration is deprecated an it is recommended to switch to a connection string. You can find your instrumentation key in your Application Insights resource. + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +[Configuration and Extension]: ../README.md#configuration-and-extension +[Azure Application Insights Service]: https://learn.microsoft.com/en-us/azure/azure-monitor/app/java-in-process-agent diff --git a/lib/java_buildpack/framework/azure_application_insights_agent.rb b/lib/java_buildpack/framework/azure_application_insights_agent.rb index f47d21527f..7e13587627 100644 --- a/lib/java_buildpack/framework/azure_application_insights_agent.rb +++ b/lib/java_buildpack/framework/azure_application_insights_agent.rb @@ -33,25 +33,32 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, INSTRUMENTATION_KEY)['credentials'] + credentials = @application.services.find_service(FILTER, CONNECTION_STRING, INSTRUMENTATION_KEY)['credentials'] - @droplet - .java_opts.add_javaagent(@droplet.sandbox + jar_name) - .add_system_property('APPLICATION_INSIGHTS_IKEY', credentials[INSTRUMENTATION_KEY]) + if credentials.key?(CONNECTION_STRING) + @droplet.java_opts.add_system_property('applicationinsights.connection.string', + credentials[CONNECTION_STRING]) + end + if credentials.key?(INSTRUMENTATION_KEY) + @droplet.java_opts.add_system_property('APPLICATION_INSIGHTS_IKEY', + credentials[INSTRUMENTATION_KEY]) + end + @droplet.java_opts.add_javaagent(@droplet.sandbox + jar_name) end protected # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service? FILTER, INSTRUMENTATION_KEY + @application.services.one_service?(FILTER, CONNECTION_STRING, INSTRUMENTATION_KEY) end FILTER = /azure-application-insights/.freeze + CONNECTION_STRING = 'connection_string' INSTRUMENTATION_KEY = 'instrumentation_key' - private_constant :FILTER, :INSTRUMENTATION_KEY + private_constant :FILTER, :CONNECTION_STRING, :INSTRUMENTATION_KEY end diff --git a/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb b/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb index 88a3138421..85f11c7e1f 100644 --- a/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb +++ b/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb @@ -33,7 +33,9 @@ context do before do - allow(services).to receive(:one_service?).with(/azure-application-insights/, 'instrumentation_key') + allow(services).to receive(:one_service?).with(/azure-application-insights/, + 'connection_string', + 'instrumentation_key') .and_return(true) end @@ -59,12 +61,14 @@ it 'updates JAVA_OPTS' do allow(services).to receive(:find_service) - .and_return('credentials' => { 'instrumentation_key' => 'test-instrumentation-key' }) + .and_return('credentials' => { 'connection_string' => 'test-connection-string', + 'instrumentation_key' => 'test-instrumentation-key' }) component.release expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/azure_application_insights_agent/' \ "azure_application_insights_agent-#{version}.jar") + expect(java_opts).to include('-Dapplicationinsights.connection.string=test-connection-string') expect(java_opts).to include('-DAPPLICATION_INSIGHTS_IKEY=test-instrumentation-key') end From d0e62f7297629672bf196c726b45bac3c2fbaf5d Mon Sep 17 00:00:00 2001 From: Stefan Mayr Date: Sun, 13 Nov 2022 13:45:13 +0100 Subject: [PATCH 705/812] Update default Azure Application Insights Agent version --- config/azure_application_insights_agent.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/azure_application_insights_agent.yml b/config/azure_application_insights_agent.yml index 1827271bcd..4199801339 100644 --- a/config/azure_application_insights_agent.yml +++ b/config/azure_application_insights_agent.yml @@ -15,5 +15,5 @@ # Configuration for the Azure Application Insights framework. --- -version: 2.+ -repository_root: https://java-buildpack.cloudfoundry.org/azure-application-insights +version: 3.+ +repository_root: "{default.repository.root}/azure-application-insights" From 7c5291aa87a220ef1cf036f7539b24851033f477 Mon Sep 17 00:00:00 2001 From: Stefan Mayr Date: Sun, 13 Nov 2022 19:23:57 +0100 Subject: [PATCH 706/812] Use default.repository.root for Sky Walking Framework (#983) --- config/sky_walking_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sky_walking_agent.yml b/config/sky_walking_agent.yml index 04048bd6d1..dd8f25892c 100644 --- a/config/sky_walking_agent.yml +++ b/config/sky_walking_agent.yml @@ -16,5 +16,5 @@ # Configuration for the Sky Walking framework. --- version: + -repository_root: https://java-buildpack.cloudfoundry.org/sky-walking +repository_root: "{default.repository.root}/sky-walking" default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") From 39b156cd4846f783dad7e7ba2e7d283e2dcd9d4d Mon Sep 17 00:00:00 2001 From: Stefan Mayr Date: Mon, 14 Nov 2022 23:51:11 +0100 Subject: [PATCH 707/812] Add env var APPINSIGHTS_INSTRUMENTATIONKEY for compatibility --- .../framework/azure_application_insights_agent.rb | 4 ++++ .../framework/azure_application_insights_agent_spec.rb | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/lib/java_buildpack/framework/azure_application_insights_agent.rb b/lib/java_buildpack/framework/azure_application_insights_agent.rb index 7e13587627..474e43f317 100644 --- a/lib/java_buildpack/framework/azure_application_insights_agent.rb +++ b/lib/java_buildpack/framework/azure_application_insights_agent.rb @@ -42,6 +42,10 @@ def release if credentials.key?(INSTRUMENTATION_KEY) @droplet.java_opts.add_system_property('APPLICATION_INSIGHTS_IKEY', credentials[INSTRUMENTATION_KEY]) + # add environment variable for compatibility with agent version 3.x + # this triggers a warning message to switch to connection string + @droplet.environment_variables.add_environment_variable('APPINSIGHTS_INSTRUMENTATIONKEY', + credentials[INSTRUMENTATION_KEY]) end @droplet.java_opts.add_javaagent(@droplet.sandbox + jar_name) end diff --git a/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb b/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb index 85f11c7e1f..c68d1933d9 100644 --- a/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb +++ b/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb @@ -72,6 +72,15 @@ expect(java_opts).to include('-DAPPLICATION_INSIGHTS_IKEY=test-instrumentation-key') end + it 'updates environment variables' do + allow(services).to receive(:find_service) + .and_return('credentials' => { 'instrumentation_key' => 'test-instrumentation-key' }) + + component.release + + expect(environment_variables).to include('APPINSIGHTS_INSTRUMENTATIONKEY=test-instrumentation-key') + end + end end From ed390252f2a80b61b45f49ed4e8489d3f0a6986b Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Fri, 2 Dec 2022 14:02:35 +0000 Subject: [PATCH 708/812] Fixes issues with rbenv --- ci/Dockerfile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ci/Dockerfile b/ci/Dockerfile index 7f81843607..8eef8ddf5a 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -19,11 +19,7 @@ RUN locale-gen en_US.UTF-8 \ && /usr/sbin/update-locale LANG=en_US.UTF-8 \ && dpkg-reconfigure -f noninteractive locales -RUN git clone https://github.com/rbenv/rbenv.git $HOME/.rbenv \ - && cd $HOME/.rbenv \ - && src/configure \ - && make -C src \ - && ln -s $HOME/.rbenv/bin/rbenv /usr/local/bin +RUN git clone https://github.com/rbenv/rbenv.git $HOME/.rbenv && ln -s $HOME/.rbenv/libexec/rbenv /usr/local/bin RUN eval "$(rbenv init -)" \ && git clone https://github.com/rbenv/ruby-build.git $(rbenv root)/plugins/ruby-build From 10ea15aee24115eb5fdf47a48ad48d203ede03a0 Mon Sep 17 00:00:00 2001 From: Rene Bamberger Date: Mon, 5 Dec 2022 15:24:01 +0100 Subject: [PATCH 709/812] Remove sensitive information from URI query parameters --- lib/java_buildpack/util/sanitizer.rb | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index c2dbac667f..68f6a26a37 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -22,11 +22,32 @@ class String # # @return [String] the sanitized uri def sanitize_uri + keywords = /key|password|username|cred[entials]*[s]*|password|token|api[-_]token|api|auth[entication]*|access[-_]token|secret[-_]token/i + rich_uri = URI(self) rich_uri.user = nil rich_uri.password = nil - rich_uri.query = rich_uri.query&.gsub(/(Api-Token=dt\w*\.\w*)\.\w*/, '\1.REDACTED') + + if(rich_uri.query) + params = Hash[URI.decode_www_form rich_uri.query] + + query_params = "" + + params.each do |key,value| + match = key.match(keywords) + + if(match) + if(match[0] == "Api-Token" && value =~ /dt\w*/) + params[key] = value.gsub(/(dt\w*\.\w*)\.\w*/, '\1.REDACTED') + else + params[key] = "***" + end + end + + query_params += key + "=" + params[key] + "&" + end + rich_uri.query = query_params.chop + end rich_uri.to_s end - end From 222c3ca96343ad48e57d2c6b0ee5b673056d6d98 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 14 Dec 2022 10:51:28 +0000 Subject: [PATCH 710/812] Adds packaging config info for Splunk --- config/packaging.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/packaging.yml b/config/packaging.yml index 74eaea3692..3cd9343b48 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -168,6 +168,10 @@ sky_walking_agent: name: SkyWalking release_notes: '[ChangeLog](https://github.com/apache/skywalking/tree/master/changes)' +splunk_otel_java_agent: + name: Splunk OpenTelemetry Java Agent + release_notes: '[Release Notes](https://github.com/signalfx/splunk-otel-java/releases)' + spring_auto_reconfiguration: name: Spring Auto-reconfiguration cve_notes: 'Included inline above' From 0ca3298189d2cc0617c02d65dcc5bab33145ac2f Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 12 Jan 2023 12:21:50 +0000 Subject: [PATCH 711/812] Fixed issue with offline packaging for cflinuxfs4/jammy --- rakelib/package.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rakelib/package.rb b/rakelib/package.rb index 5fffb464ac..5e38fbfbe1 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -73,7 +73,7 @@ def self.version BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze - PLATFORMS = %w[bionic].freeze + PLATFORMS = %w[bionic jammy].freeze STAGING_DIR = "#{BUILD_DIR}/staging".freeze From d554437285480927bdc7874f9f91250d6e2c7e91 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Fri, 13 Jan 2023 16:30:06 +0000 Subject: [PATCH 712/812] Dockerfile ruby fix --- ci/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile b/ci/Dockerfile index 8eef8ddf5a..93f606f161 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -26,7 +26,7 @@ RUN eval "$(rbenv init -)" \ RUN eval "$(rbenv init -)" \ && git clone https://github.com/sstephenson/rbenv-default-gems.git $(rbenv root)/plugins/rbenv-default-gems \ - && echo 'bundler' >> $(rbenv root)/default-gems + && echo 'bundler 2.3.26' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ && rbenv install 2.5.9 From 5b06859907b4f3aab50600fa2f7a20f356c81798 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 19 Jan 2023 17:35:09 +0000 Subject: [PATCH 713/812] Quarterly Java release note updates --- config/packaging.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index 3cd9343b48..e6bcf61337 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -93,17 +93,17 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u352/)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u362/)' jre-11: name: OpenJDK JRE 11 cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.17/)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.18/)' jre-17: name: OpenJDK JRE 17 cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.5/)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.6/)' jrebel_agent: name: JRebel Agent From f73c65b428425ead78df5a9847453bb13cbfd681 Mon Sep 17 00:00:00 2001 From: Rene Bamberger Date: Mon, 23 Jan 2023 08:28:41 +0100 Subject: [PATCH 714/812] Tests added --- lib/java_buildpack/util/sanitizer.rb | 59 +++++++++++++++-------- spec/java_buildpack/util/sanitize_spec.rb | 18 ++++++- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index 68f6a26a37..eafb4729b7 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -18,36 +18,55 @@ # A mixin that adds the ability to turn a +String+ into sanitized uri class String + # Takes the uri query params and strips out credentials + # + # @return [String] the sanitized query params + def handle_params(params) + keywords = /key + |password + |username + |cred(ential)*(s)* + |password + |token + |api[-_]token + |api + |auth(entication)* + |access[-_]token + |secret[-_]token/ix + + query_params = '' + + params.each do |key, value| + match = key.match(keywords) + + if match + params[key] = if match[0] == 'Api-Token' && value =~ /dt\w*/ + value.gsub(/(dt\w*\.\w*)\.\w*/, '\1.REDACTED') + else + '***' + end + end + + query_params += key + '=' + params[key] + '&' + end + + query_params + end + # Takes a uri and strips out any credentials it may contain. # # @return [String] the sanitized uri def sanitize_uri - keywords = /key|password|username|cred[entials]*[s]*|password|token|api[-_]token|api|auth[entication]*|access[-_]token|secret[-_]token/i - rich_uri = URI(self) rich_uri.user = nil rich_uri.password = nil - if(rich_uri.query) - params = Hash[URI.decode_www_form rich_uri.query] - - query_params = "" - - params.each do |key,value| - match = key.match(keywords) - - if(match) - if(match[0] == "Api-Token" && value =~ /dt\w*/) - params[key] = value.gsub(/(dt\w*\.\w*)\.\w*/, '\1.REDACTED') - else - params[key] = "***" - end - end - - query_params += key + "=" + params[key] + "&" - end + if rich_uri.query + params = (URI.decode_www_form rich_uri.query).to_h + query_params = handle_params(params) rich_uri.query = query_params.chop end + rich_uri.to_s end end diff --git a/spec/java_buildpack/util/sanitize_spec.rb b/spec/java_buildpack/util/sanitize_spec.rb index 290243e18b..59609ea91d 100644 --- a/spec/java_buildpack/util/sanitize_spec.rb +++ b/spec/java_buildpack/util/sanitize_spec.rb @@ -23,7 +23,23 @@ include_context 'with application help' it 'sanitizes uri with credentials in' do - expect('https://myuser:mypass@myhost/path/to/file'.sanitize_uri).to eq('https://myhost/path/to/file') + expect('https://myuser:mypass@myhost/path/to/file'\ + '?authentication=verysecret'\ + '&cred=verysecret'\ + '&password=verysecret'\ + '&include=java'\ + '&bitness=64'\ + '&Api-Token=dt0c01.H67ALCXCXK7PWAAOQLENSRET.PRIVATEPART'\ + '&secret-token=verysecret'\ + '&token=123456789'.sanitize_uri).to eq('https://myhost/path/to/file'\ + '?authentication=***'\ + '&cred=***'\ + '&password=***'\ + '&include=java'\ + '&bitness=64'\ + '&Api-Token=dt0c01.H67ALCXCXK7PWAAOQLENSRET.REDACTED'\ + '&secret-token=***'\ + '&token=***') end it 'does not sanatize uri with no credentials in' do From 711a1cb463c4a2f5664df049d858d8844c145348 Mon Sep 17 00:00:00 2001 From: Moshe Tsur Date: Wed, 1 Mar 2023 22:53:17 -0500 Subject: [PATCH 715/812] Re-add Takipi Agent --- config/components.yml | 1 + config/takipi_agent.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config/components.yml b/config/components.yml index 933bf1a413..475a03c8c0 100644 --- a/config/components.yml +++ b/config/components.yml @@ -75,5 +75,6 @@ frameworks: - "JavaBuildpack::Framework::SpringInsight" - "JavaBuildpack::Framework::SkyWalkingAgent" - "JavaBuildpack::Framework::YourKitProfiler" + - "JavaBuildpack::Framework::TakipiAgent" - "JavaBuildpack::Framework::JavaSecurity" - "JavaBuildpack::Framework::JavaOpts" diff --git a/config/takipi_agent.yml b/config/takipi_agent.yml index 7a30931bac..dd8407034e 100644 --- a/config/takipi_agent.yml +++ b/config/takipi_agent.yml @@ -16,6 +16,6 @@ # Configuration for the Takipi framework --- version: 4.+ -repository_root: "" +repository_root: https://get.takipi.com/cloudfoundry node_name_prefix: node application_name: From f5691fbb6868fa737729d2d3887194b7cf620052 Mon Sep 17 00:00:00 2001 From: Ben Ross Date: Fri, 3 Mar 2023 09:05:55 -0800 Subject: [PATCH 716/812] Update geode_store version to 1.13.7 --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index ce26c5b94d..d6c1a2ac61 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -42,5 +42,5 @@ redis_store: geode_store: # The version of Geode Store must be less than or equal to your Tanzu Gemfire for VMs version to ensure compatibility. # The Geode Store version is pinned to 1.12.4 to be compatible with the most commonly used versions of Tanzu Gemfire for VMs. - version: 1.12.5 + version: 1.13.7 repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From 5c0a32d528fe7f39c5a45831fab4bf07a80ce9ca Mon Sep 17 00:00:00 2001 From: Ryan Moran Date: Tue, 14 Feb 2023 15:55:01 -0800 Subject: [PATCH 717/812] Rewrites buildpack entrypoints to install Ruby before executing - the bin/{compile,detect,finalize,release} executables have been wrapped in a small shim that makes sure a Ruby interpreter is available on the PATH before exec-ing the existing buildpack entrypoints - works both online and offline - currently pinned to the latest Ruby 3.1.x version available in the Ruby Buildpack repository --- bin/compile | 28 +------- bin/detect | 36 +--------- bin/finalize | 30 +-------- bin/release | 30 +-------- bin/ruby-run | 50 ++++++++++++++ bin/run | 109 +++++++++++++++++++++++++++++++ config/ruby.yml | 19 ++++++ rakelib/dependency_cache_task.rb | 2 +- 8 files changed, 183 insertions(+), 121 deletions(-) mode change 100755 => 120000 bin/compile mode change 100755 => 120000 bin/detect mode change 100755 => 120000 bin/finalize mode change 100755 => 120000 bin/release create mode 100755 bin/ruby-run create mode 100755 bin/run create mode 100644 config/ruby.yml diff --git a/bin/compile b/bin/compile deleted file mode 100755 index bf6d6650e8..0000000000 --- a/bin/compile +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) diff --git a/bin/compile b/bin/compile new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/compile @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/detect b/bin/detect deleted file mode 100755 index c0552f2f3b..0000000000 --- a/bin/detect +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', - &:detect).compact - -if components.empty? - abort -else - str = components.join(' ') - puts str.length > 255 ? str.slice(0..251) + '...' : str -end diff --git a/bin/detect b/bin/detect new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/detect @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/finalize b/bin/finalize deleted file mode 100755 index b1d3b95e03..0000000000 --- a/bin/finalize +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] -deps_dir = ARGV[2] -index = ARGV[3] - -JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) diff --git a/bin/finalize b/bin/finalize new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/finalize @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/release b/bin/release deleted file mode 100755 index 0882a48d99..0000000000 --- a/bin/release +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) - -puts output diff --git a/bin/release b/bin/release new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/release @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/ruby-run b/bin/ruby-run new file mode 100755 index 0000000000..598cb27d6a --- /dev/null +++ b/bin/ruby-run @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +$stdout.sync = true +$stderr.sync = true +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) +require 'java_buildpack/buildpack' + +case ARGV[0] + when "compile" + app_dir = ARGV[1] + JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) + + when "detect" + app_dir = ARGV[1] + components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', + &:detect).compact + if components.empty? + abort + else + str = components.join(' ') + puts str.length > 255 ? str.slice(0..251) + '...' : str + end + + when "finalize" + app_dir = ARGV[1] + deps_dir = ARGV[3] + index = ARGV[4] + JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) + + when "release" + app_dir = ARGV[1] + output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) + puts output +end diff --git a/bin/run b/bin/run new file mode 100755 index 0000000000..c4bd677b81 --- /dev/null +++ b/bin/run @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +set -e +set -u +set -o pipefail + +BUILDPACK_DIR="$(cd "$(dirname "${0}")/.." && pwd)" +readonly BUILDPACK_DIR + +RUBY_DIR="/tmp/ruby" +readonly RUBY_DIR + +function util::config::lookup() { + sed '/^#/d' < "${BUILDPACK_DIR}/config/ruby.yml" +} + +function util::cache::present() { + if [[ -e "${BUILDPACK_DIR}/resources/cache" ]]; then + return 0 + else + return 1 + fi +} + +function util::index::lookup() { + local repository_root + repository_root="$(grep "repository_root" <<< "$(util::config::lookup)" | cut -d' ' -f2)" + + local uri + uri="${repository_root}/index.yml" + + if util::cache::present; then + local sha + sha="$(printf "%s" "${uri}" | shasum -a 256 | cut -d' ' -f1)" + cat "${BUILDPACK_DIR}/resources/cache/${sha}.cached" + else + curl -ssL "${uri}" + fi +} + +function util::semver::parse() { + local version major minor patch + version="$(grep "version" <<< "$(util::config::lookup)" | cut -d' ' -f2)" + major="$(cut -d'.' -f1 <<< "${version}")" + minor="$(cut -d'.' -f2 <<< "${version}")" + patch="$(cut -d'.' -f3 <<< "${version}")" + + printf "%s" "${major/+/*}\\.${minor/+/*}\\.${patch/+/*}" +} + +function util::ruby::stream() { + local uri + uri="${1}" + + if util::cache::present; then + local sha + sha="$(printf "%s" "${uri}" | shasum -a 256 | cut -d' ' -f1)" + cat "${BUILDPACK_DIR}/resources/cache/${sha}.cached" + else + curl -ssL "${uri}" + fi +} + +function util::install() { + local index semver + index="$(util::index::lookup)" + semver="$(util::semver::parse)" + + local uri + uri="$(grep "${semver}" <<< "${index}" | head -n 1 | awk '{print $2}')" + + util::ruby::stream "${uri}" | tar xz -C "${RUBY_DIR}" +} + +function util::print::error() { + local message red reset + message="${1}" + red="\033[0;31m" + reset="\033[0;39m" + + echo -e "${red}${message}${reset}" >&2 + exit 1 +} + +function util::environment::setup() { + export PATH="${RUBY_DIR}/bin:${PATH:-}" + export LIBRARY_PATH="${RUBY_DIR}/lib:${LIBRARY_PATH:-}" + export LD_LIBRARY_PATH="${RUBY_DIR}/lib:${LIBRARY_PATH:-}" + export CPATH="${RUBY_DIR}/include:${CPATH:-}" +} + +function main() { + local phase + phase="$(basename "${0}")" + + if [[ "${CF_STACK}" == "cflinuxfs4" ]]; then + if [[ ! -e "${RUBY_DIR}" ]]; then + mkdir -p "${RUBY_DIR}" + + util::install + fi + + util::environment::setup + fi + + exec "${BUILDPACK_DIR}/bin/ruby-run" "${phase}" "${@-}" +} + +main "${@:-}" diff --git a/config/ruby.yml b/config/ruby.yml new file mode 100644 index 0000000000..bb36ccf0e2 --- /dev/null +++ b/config/ruby.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for Ruby +--- +version: 3.1.+ +repository_root: https://raw.githubusercontent.com/cloudfoundry/ruby-buildpack/develop/java-index diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 01a1512a47..3e07630160 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -119,7 +119,7 @@ def component_ids offline_cache = offline_cache.split(',') (conf << offline_cache).flatten!.uniq! end - conf + conf << "ruby" end def component_configuration(component_id) From d82fe0d07ccb4603a0626e51b807a3d15721f2de Mon Sep 17 00:00:00 2001 From: Ryan Moran Date: Thu, 9 Mar 2023 15:22:16 -0800 Subject: [PATCH 718/812] Revert "Rewrites buildpack entrypoints to install Ruby before executing" This reverts commit 5c0a32d528fe7f39c5a45831fab4bf07a80ce9ca. --- bin/compile | 28 +++++++- bin/detect | 36 +++++++++- bin/finalize | 30 ++++++++- bin/release | 30 ++++++++- bin/ruby-run | 50 -------------- bin/run | 109 ------------------------------- config/ruby.yml | 19 ------ rakelib/dependency_cache_task.rb | 2 +- 8 files changed, 121 insertions(+), 183 deletions(-) mode change 120000 => 100755 bin/compile mode change 120000 => 100755 bin/detect mode change 120000 => 100755 bin/finalize mode change 120000 => 100755 bin/release delete mode 100755 bin/ruby-run delete mode 100755 bin/run delete mode 100644 config/ruby.yml diff --git a/bin/compile b/bin/compile deleted file mode 120000 index 84db910f22..0000000000 --- a/bin/compile +++ /dev/null @@ -1 +0,0 @@ -./run \ No newline at end of file diff --git a/bin/compile b/bin/compile new file mode 100755 index 0000000000..bf6d6650e8 --- /dev/null +++ b/bin/compile @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +$stdout.sync = true +$stderr.sync = true +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) + +require 'java_buildpack/buildpack' + +app_dir = ARGV[0] + +JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) diff --git a/bin/detect b/bin/detect deleted file mode 120000 index 84db910f22..0000000000 --- a/bin/detect +++ /dev/null @@ -1 +0,0 @@ -./run \ No newline at end of file diff --git a/bin/detect b/bin/detect new file mode 100755 index 0000000000..c0552f2f3b --- /dev/null +++ b/bin/detect @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +$stdout.sync = true +$stderr.sync = true +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) + +require 'java_buildpack/buildpack' + +app_dir = ARGV[0] + +components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', + &:detect).compact + +if components.empty? + abort +else + str = components.join(' ') + puts str.length > 255 ? str.slice(0..251) + '...' : str +end diff --git a/bin/finalize b/bin/finalize deleted file mode 120000 index 84db910f22..0000000000 --- a/bin/finalize +++ /dev/null @@ -1 +0,0 @@ -./run \ No newline at end of file diff --git a/bin/finalize b/bin/finalize new file mode 100755 index 0000000000..b1d3b95e03 --- /dev/null +++ b/bin/finalize @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +$stdout.sync = true +$stderr.sync = true +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) + +require 'java_buildpack/buildpack' + +app_dir = ARGV[0] +deps_dir = ARGV[2] +index = ARGV[3] + +JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) diff --git a/bin/release b/bin/release deleted file mode 120000 index 84db910f22..0000000000 --- a/bin/release +++ /dev/null @@ -1 +0,0 @@ -./run \ No newline at end of file diff --git a/bin/release b/bin/release new file mode 100755 index 0000000000..0882a48d99 --- /dev/null +++ b/bin/release @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +$stdout.sync = true +$stderr.sync = true +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) + +require 'java_buildpack/buildpack' + +app_dir = ARGV[0] + +output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) + +puts output diff --git a/bin/ruby-run b/bin/ruby-run deleted file mode 100755 index 598cb27d6a..0000000000 --- a/bin/ruby-run +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) -require 'java_buildpack/buildpack' - -case ARGV[0] - when "compile" - app_dir = ARGV[1] - JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) - - when "detect" - app_dir = ARGV[1] - components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', - &:detect).compact - if components.empty? - abort - else - str = components.join(' ') - puts str.length > 255 ? str.slice(0..251) + '...' : str - end - - when "finalize" - app_dir = ARGV[1] - deps_dir = ARGV[3] - index = ARGV[4] - JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) - - when "release" - app_dir = ARGV[1] - output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) - puts output -end diff --git a/bin/run b/bin/run deleted file mode 100755 index c4bd677b81..0000000000 --- a/bin/run +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -u -set -o pipefail - -BUILDPACK_DIR="$(cd "$(dirname "${0}")/.." && pwd)" -readonly BUILDPACK_DIR - -RUBY_DIR="/tmp/ruby" -readonly RUBY_DIR - -function util::config::lookup() { - sed '/^#/d' < "${BUILDPACK_DIR}/config/ruby.yml" -} - -function util::cache::present() { - if [[ -e "${BUILDPACK_DIR}/resources/cache" ]]; then - return 0 - else - return 1 - fi -} - -function util::index::lookup() { - local repository_root - repository_root="$(grep "repository_root" <<< "$(util::config::lookup)" | cut -d' ' -f2)" - - local uri - uri="${repository_root}/index.yml" - - if util::cache::present; then - local sha - sha="$(printf "%s" "${uri}" | shasum -a 256 | cut -d' ' -f1)" - cat "${BUILDPACK_DIR}/resources/cache/${sha}.cached" - else - curl -ssL "${uri}" - fi -} - -function util::semver::parse() { - local version major minor patch - version="$(grep "version" <<< "$(util::config::lookup)" | cut -d' ' -f2)" - major="$(cut -d'.' -f1 <<< "${version}")" - minor="$(cut -d'.' -f2 <<< "${version}")" - patch="$(cut -d'.' -f3 <<< "${version}")" - - printf "%s" "${major/+/*}\\.${minor/+/*}\\.${patch/+/*}" -} - -function util::ruby::stream() { - local uri - uri="${1}" - - if util::cache::present; then - local sha - sha="$(printf "%s" "${uri}" | shasum -a 256 | cut -d' ' -f1)" - cat "${BUILDPACK_DIR}/resources/cache/${sha}.cached" - else - curl -ssL "${uri}" - fi -} - -function util::install() { - local index semver - index="$(util::index::lookup)" - semver="$(util::semver::parse)" - - local uri - uri="$(grep "${semver}" <<< "${index}" | head -n 1 | awk '{print $2}')" - - util::ruby::stream "${uri}" | tar xz -C "${RUBY_DIR}" -} - -function util::print::error() { - local message red reset - message="${1}" - red="\033[0;31m" - reset="\033[0;39m" - - echo -e "${red}${message}${reset}" >&2 - exit 1 -} - -function util::environment::setup() { - export PATH="${RUBY_DIR}/bin:${PATH:-}" - export LIBRARY_PATH="${RUBY_DIR}/lib:${LIBRARY_PATH:-}" - export LD_LIBRARY_PATH="${RUBY_DIR}/lib:${LIBRARY_PATH:-}" - export CPATH="${RUBY_DIR}/include:${CPATH:-}" -} - -function main() { - local phase - phase="$(basename "${0}")" - - if [[ "${CF_STACK}" == "cflinuxfs4" ]]; then - if [[ ! -e "${RUBY_DIR}" ]]; then - mkdir -p "${RUBY_DIR}" - - util::install - fi - - util::environment::setup - fi - - exec "${BUILDPACK_DIR}/bin/ruby-run" "${phase}" "${@-}" -} - -main "${@:-}" diff --git a/config/ruby.yml b/config/ruby.yml deleted file mode 100644 index bb36ccf0e2..0000000000 --- a/config/ruby.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Configuration for Ruby ---- -version: 3.1.+ -repository_root: https://raw.githubusercontent.com/cloudfoundry/ruby-buildpack/develop/java-index diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 3e07630160..01a1512a47 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -119,7 +119,7 @@ def component_ids offline_cache = offline_cache.split(',') (conf << offline_cache).flatten!.uniq! end - conf << "ruby" + conf end def component_configuration(component_id) From 215c6c7db801901321f4f2c62a538a816e59c0ba Mon Sep 17 00:00:00 2001 From: Ryan Moran Date: Tue, 14 Feb 2023 15:55:01 -0800 Subject: [PATCH 719/812] Rewrites buildpack entrypoints to install Ruby before executing - the bin/{compile,detect,finalize,release} executables have been wrapped in a small shim that makes sure a Ruby interpreter is available on the PATH before exec-ing the existing buildpack entrypoints - works both online and offline - currently pinned to the latest Ruby 3.1.x version available in the Ruby Buildpack repository --- bin/compile | 28 +------- bin/detect | 36 +--------- bin/finalize | 30 +-------- bin/release | 30 +-------- bin/ruby-run | 50 ++++++++++++++ bin/run | 109 +++++++++++++++++++++++++++++++ config/ruby.yml | 19 ++++++ rakelib/dependency_cache_task.rb | 2 +- 8 files changed, 183 insertions(+), 121 deletions(-) mode change 100755 => 120000 bin/compile mode change 100755 => 120000 bin/detect mode change 100755 => 120000 bin/finalize mode change 100755 => 120000 bin/release create mode 100755 bin/ruby-run create mode 100755 bin/run create mode 100644 config/ruby.yml diff --git a/bin/compile b/bin/compile deleted file mode 100755 index bf6d6650e8..0000000000 --- a/bin/compile +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) diff --git a/bin/compile b/bin/compile new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/compile @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/detect b/bin/detect deleted file mode 100755 index c0552f2f3b..0000000000 --- a/bin/detect +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', - &:detect).compact - -if components.empty? - abort -else - str = components.join(' ') - puts str.length > 255 ? str.slice(0..251) + '...' : str -end diff --git a/bin/detect b/bin/detect new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/detect @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/finalize b/bin/finalize deleted file mode 100755 index b1d3b95e03..0000000000 --- a/bin/finalize +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] -deps_dir = ARGV[2] -index = ARGV[3] - -JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) diff --git a/bin/finalize b/bin/finalize new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/finalize @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/release b/bin/release deleted file mode 100755 index 0882a48d99..0000000000 --- a/bin/release +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) - -puts output diff --git a/bin/release b/bin/release new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/release @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/ruby-run b/bin/ruby-run new file mode 100755 index 0000000000..598cb27d6a --- /dev/null +++ b/bin/ruby-run @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +$stdout.sync = true +$stderr.sync = true +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) +require 'java_buildpack/buildpack' + +case ARGV[0] + when "compile" + app_dir = ARGV[1] + JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) + + when "detect" + app_dir = ARGV[1] + components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', + &:detect).compact + if components.empty? + abort + else + str = components.join(' ') + puts str.length > 255 ? str.slice(0..251) + '...' : str + end + + when "finalize" + app_dir = ARGV[1] + deps_dir = ARGV[3] + index = ARGV[4] + JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) + + when "release" + app_dir = ARGV[1] + output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) + puts output +end diff --git a/bin/run b/bin/run new file mode 100755 index 0000000000..c4bd677b81 --- /dev/null +++ b/bin/run @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +set -e +set -u +set -o pipefail + +BUILDPACK_DIR="$(cd "$(dirname "${0}")/.." && pwd)" +readonly BUILDPACK_DIR + +RUBY_DIR="/tmp/ruby" +readonly RUBY_DIR + +function util::config::lookup() { + sed '/^#/d' < "${BUILDPACK_DIR}/config/ruby.yml" +} + +function util::cache::present() { + if [[ -e "${BUILDPACK_DIR}/resources/cache" ]]; then + return 0 + else + return 1 + fi +} + +function util::index::lookup() { + local repository_root + repository_root="$(grep "repository_root" <<< "$(util::config::lookup)" | cut -d' ' -f2)" + + local uri + uri="${repository_root}/index.yml" + + if util::cache::present; then + local sha + sha="$(printf "%s" "${uri}" | shasum -a 256 | cut -d' ' -f1)" + cat "${BUILDPACK_DIR}/resources/cache/${sha}.cached" + else + curl -ssL "${uri}" + fi +} + +function util::semver::parse() { + local version major minor patch + version="$(grep "version" <<< "$(util::config::lookup)" | cut -d' ' -f2)" + major="$(cut -d'.' -f1 <<< "${version}")" + minor="$(cut -d'.' -f2 <<< "${version}")" + patch="$(cut -d'.' -f3 <<< "${version}")" + + printf "%s" "${major/+/*}\\.${minor/+/*}\\.${patch/+/*}" +} + +function util::ruby::stream() { + local uri + uri="${1}" + + if util::cache::present; then + local sha + sha="$(printf "%s" "${uri}" | shasum -a 256 | cut -d' ' -f1)" + cat "${BUILDPACK_DIR}/resources/cache/${sha}.cached" + else + curl -ssL "${uri}" + fi +} + +function util::install() { + local index semver + index="$(util::index::lookup)" + semver="$(util::semver::parse)" + + local uri + uri="$(grep "${semver}" <<< "${index}" | head -n 1 | awk '{print $2}')" + + util::ruby::stream "${uri}" | tar xz -C "${RUBY_DIR}" +} + +function util::print::error() { + local message red reset + message="${1}" + red="\033[0;31m" + reset="\033[0;39m" + + echo -e "${red}${message}${reset}" >&2 + exit 1 +} + +function util::environment::setup() { + export PATH="${RUBY_DIR}/bin:${PATH:-}" + export LIBRARY_PATH="${RUBY_DIR}/lib:${LIBRARY_PATH:-}" + export LD_LIBRARY_PATH="${RUBY_DIR}/lib:${LIBRARY_PATH:-}" + export CPATH="${RUBY_DIR}/include:${CPATH:-}" +} + +function main() { + local phase + phase="$(basename "${0}")" + + if [[ "${CF_STACK}" == "cflinuxfs4" ]]; then + if [[ ! -e "${RUBY_DIR}" ]]; then + mkdir -p "${RUBY_DIR}" + + util::install + fi + + util::environment::setup + fi + + exec "${BUILDPACK_DIR}/bin/ruby-run" "${phase}" "${@-}" +} + +main "${@:-}" diff --git a/config/ruby.yml b/config/ruby.yml new file mode 100644 index 0000000000..40287d4227 --- /dev/null +++ b/config/ruby.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for Ruby +--- +version: 3.1.+ +repository_root: https://raw.githubusercontent.com/cloudfoundry/ruby-buildpack/master/java-index diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 01a1512a47..3e07630160 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -119,7 +119,7 @@ def component_ids offline_cache = offline_cache.split(',') (conf << offline_cache).flatten!.uniq! end - conf + conf << "ruby" end def component_configuration(component_id) From 017b8f196049abc897ee57643b728a8793496f6c Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Mon, 20 Mar 2023 12:38:47 +0000 Subject: [PATCH 720/812] Fixes rubocop violations --- bin/ruby-run | 44 ++++++++++++++++---------------- rakelib/dependency_cache_task.rb | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bin/ruby-run b/bin/ruby-run index 598cb27d6a..c8188ae68b 100755 --- a/bin/ruby-run +++ b/bin/ruby-run @@ -22,29 +22,29 @@ $LOAD_PATH.unshift File.expand_path('../lib', __dir__) require 'java_buildpack/buildpack' case ARGV[0] - when "compile" - app_dir = ARGV[1] - JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) +when 'compile' + app_dir = ARGV[1] + JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) - when "detect" - app_dir = ARGV[1] - components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', - &:detect).compact - if components.empty? - abort - else - str = components.join(' ') - puts str.length > 255 ? str.slice(0..251) + '...' : str - end +when 'detect' + app_dir = ARGV[1] + components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', + &:detect).compact + if components.empty? + abort + else + str = components.join(' ') + puts str.length > 255 ? str.slice(0..251) + '...' : str + end - when "finalize" - app_dir = ARGV[1] - deps_dir = ARGV[3] - index = ARGV[4] - JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) +when 'finalize' + app_dir = ARGV[1] + deps_dir = ARGV[3] + index = ARGV[4] + JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) - when "release" - app_dir = ARGV[1] - output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) - puts output +when 'release' + app_dir = ARGV[1] + output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) + puts output end diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 3e07630160..12d3d54845 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -119,7 +119,7 @@ def component_ids offline_cache = offline_cache.split(',') (conf << offline_cache).flatten!.uniq! end - conf << "ruby" + conf << 'ruby' end def component_configuration(component_id) From 67ff5963500dd2e1876afaab5f804a74b88026f1 Mon Sep 17 00:00:00 2001 From: Ryan Moran Date: Mon, 20 Mar 2023 15:53:21 -0700 Subject: [PATCH 721/812] Default to empty string if CF_STACK unbound --- bin/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/run b/bin/run index c4bd677b81..f090e8a896 100755 --- a/bin/run +++ b/bin/run @@ -93,7 +93,7 @@ function main() { local phase phase="$(basename "${0}")" - if [[ "${CF_STACK}" == "cflinuxfs4" ]]; then + if [[ "${CF_STACK:-}" == "cflinuxfs4" ]]; then if [[ ! -e "${RUBY_DIR}" ]]; then mkdir -p "${RUBY_DIR}" From 387ffcf31731d0c7fc4b5832de61dda6cfc6fc50 Mon Sep 17 00:00:00 2001 From: Ryan Moran Date: Mon, 20 Mar 2023 16:36:25 -0700 Subject: [PATCH 722/812] Adds CI/Rubocop support for Ruby 3.1 --- .rubocop.yml | 4 ++++ ci/Dockerfile | 3 +++ 2 files changed, 7 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index b9ffa2b3fe..17d9be63ca 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -71,3 +71,7 @@ Lint/RedundantCopDisableDirective: Enabled: false # disabled as this can be tough to manage across multiple ruby versions Style/RedundantFreeze: Enabled: false # enable when we only support ruby 3.0+ +Naming/BlockForwarding: + Enabled: false # enable when we only support Ruby 3.1+ +Style/HashSyntax: + EnforcedShorthandSyntax: either diff --git a/ci/Dockerfile b/ci/Dockerfile index 93f606f161..d4ee0c6d55 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -36,3 +36,6 @@ RUN eval "$(rbenv init -)" \ RUN eval "$(rbenv init -)" \ && rbenv install 3.0.4 + +RUN eval "$(rbenv init -)" \ + && rbenv install 3.1.3 From b8e54e38760c0a143be00af0b33f52d0106053ac Mon Sep 17 00:00:00 2001 From: Ryan Moran Date: Wed, 22 Mar 2023 08:09:29 -0700 Subject: [PATCH 723/812] Don't use lsb_release to find platform --- lib/java_buildpack/repository/repository_index.rb | 4 ++-- .../repository/repository_index_spec.rb | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 06b226dec5..17529c351d 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -89,8 +89,8 @@ def platform "#{tokens[1].downcase}#{tokens[2]}" elsif `uname -s` =~ /Darwin/ 'mountainlion' - elsif !`which lsb_release 2> /dev/null`.empty? - `lsb_release -cs`.strip + elsif `cat /etc/os-release | grep '^ID=' | cut -d'=' -f 2` =~ /ubuntu/ + `cat /etc/os-release | grep '^VERSION_CODENAME=' | cut -d'=' -f 2`.strip else raise 'Unable to determine platform' end diff --git a/spec/java_buildpack/repository/repository_index_spec.rb b/spec/java_buildpack/repository/repository_index_spec.rb index 05d7bba7f8..170380c379 100644 --- a/spec/java_buildpack/repository/repository_index_spec.rb +++ b/spec/java_buildpack/repository/repository_index_spec.rb @@ -73,7 +73,8 @@ allow_any_instance_of(described_class).to receive(:`).with('uname -s').and_return('Linux') allow_any_instance_of(described_class).to receive(:`).with('uname -m').and_return('x86_64') - allow_any_instance_of(described_class).to receive(:`).with('which lsb_release 2> /dev/null').and_return('') + allow_any_instance_of(described_class).to receive(:`) + .with("cat /etc/os-release | grep '^ID=' | cut -d'=' -f 2").and_return('') allow(redhat_release).to receive(:exist?).and_return(true) allow(redhat_release).to receive(:read).and_return('CentOS release 6.4 (Final)') allow(application_cache).to receive(:get).with('centos6/x86_64/test-uri/index.yml') @@ -106,9 +107,10 @@ allow_any_instance_of(described_class).to receive(:`).with('uname -s').and_return('Linux') allow_any_instance_of(described_class).to receive(:`).with('uname -m').and_return('x86_64') - allow_any_instance_of(described_class).to receive(:`).with('which lsb_release 2> /dev/null') - .and_return('/usr/bin/lsb_release') - allow_any_instance_of(described_class).to receive(:`).with('lsb_release -cs').and_return('precise') + allow_any_instance_of(described_class).to receive(:`).with("cat /etc/os-release | grep '^ID=' | cut -d'=' -f 2") + .and_return('ubuntu') + allow_any_instance_of(described_class).to receive(:`) + .with("cat /etc/os-release | grep '^VERSION_CODENAME=' | cut -d'=' -f 2").and_return('precise') allow(application_cache).to receive(:get).with('precise/x86_64/test-uri/index.yml') .and_yield(Pathname.new('spec/fixtures/test-index.yml').open) @@ -124,7 +126,8 @@ allow_any_instance_of(File).to receive(:exists?).with('/etc/redhat-release').and_return(false) allow_any_instance_of(described_class).to receive(:`).with('uname -s').and_return('Linux') - allow_any_instance_of(described_class).to receive(:`).with('which lsb_release 2> /dev/null').and_return('') + allow_any_instance_of(described_class).to receive(:`) + .with("cat /etc/os-release | grep '^ID=' | cut -d'=' -f 2").and_return('') expect { described_class.new('{platform}/{architecture}/test-uri') } .to raise_error('Unable to determine platform') From d76a6a87aa7be9c4ff6465947bfd36f02f325dd8 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Wed, 29 Mar 2023 09:07:50 -0700 Subject: [PATCH 724/812] add splunk to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4f29fe943f..581ffe6355 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ The buildpack supports extension through the use of Git repository forking. The * [Riverbed AppInternals Agent](docs/framework-riverbed_appinternals_agent.md) ([Configuration](docs/framework-riverbed_appinternals_agent.md#configuration)) * [Sealights Agent](docs/framework-sealights_agent.md) ([Configuration](docs/framework-sealights_agent.md#configuration)) * [Seeker Security Provider](docs/framework-seeker_security_provider.md) ([Configuration](docs/framework-seeker_security_provider.md#configuration)) + * [Splunk Observability Cloud](docs/framework-splunk_otel_java_agent.md) ([Configuration](docs/framework-splunk_otel_java_agent.md#user-provided-service)) * [Spring Auto Reconfiguration](docs/framework-spring_auto_reconfiguration.md) ([Configuration](docs/framework-spring_auto_reconfiguration.md#configuration)) * [Spring Insight](docs/framework-spring_insight.md) * [SkyWalking Agent](docs/framework-sky_walking_agent.md) ([Configuration](docs/framework-sky_walking_agent.md#configuration)) From fe6f245d64d9dd7fe3896bd13a38b75cb2738e0e Mon Sep 17 00:00:00 2001 From: Samuel Chelini Date: Thu, 30 Mar 2023 01:24:19 +0000 Subject: [PATCH 725/812] fix start command and options error --- lib/java_buildpack/jre/zing_jre.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/java_buildpack/jre/zing_jre.rb b/lib/java_buildpack/jre/zing_jre.rb index daa0c44589..6f8d248757 100755 --- a/lib/java_buildpack/jre/zing_jre.rb +++ b/lib/java_buildpack/jre/zing_jre.rb @@ -26,7 +26,6 @@ module Jre class ZingJRE < OpenJDKLike # (see JavaBuildpack::Component::ModularComponent#command) def command - '' end # (see JavaBuildpack::Component::ModularComponent#sub_components) @@ -40,8 +39,8 @@ def sub_components(context) # (see JavaBuildpack::Component::BaseComponent#release) def release + @droplet.java_opts.add_preformatted_options '-XX:+ExitOnOutOfMemoryError' super - @droplet.add_preformatted_options '-XX:+ExitOnOutOfMemoryError' end end end From 5304c8c91c689ff113ca705c8e4d1ec86c69b028 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Thu, 30 Mar 2023 14:17:26 +0200 Subject: [PATCH 726/812] Distinguish platforms in SapMachine repository root URL (#1006) --- config/sap_machine_jre.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sap_machine_jre.yml b/config/sap_machine_jre.yml index c0784cded4..ab3598754a 100644 --- a/config/sap_machine_jre.yml +++ b/config/sap_machine_jre.yml @@ -21,7 +21,7 @@ jre: version_lines: - 11.+ - 17.+ - repository_root: "https://sap.github.io/SapMachine/assets/cf/jre/linux/{architecture}" + repository_root: "https://sap.github.io/SapMachine/assets/cf/jre/{platform}/{architecture}" jvmkill_agent: version: 1.+ repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" From 4d78e6f276de287a480bb522dbc0c8d1fdb70244 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Fri, 7 Apr 2023 15:11:30 +0100 Subject: [PATCH 727/812] Update Ruby check for cflinuxfs4 stack --- bin/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/run b/bin/run index f090e8a896..0782066a27 100755 --- a/bin/run +++ b/bin/run @@ -94,7 +94,7 @@ function main() { phase="$(basename "${0}")" if [[ "${CF_STACK:-}" == "cflinuxfs4" ]]; then - if [[ ! -e "${RUBY_DIR}" ]]; then + if ! which ruby > /dev/null; then mkdir -p "${RUBY_DIR}" util::install From 7991e045d8cceefff5de6102b84815bcfa0be81e Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Fri, 7 Apr 2023 16:15:25 +0100 Subject: [PATCH 728/812] Fixes rubocop issue with Zing JRE framework --- lib/java_buildpack/jre/zing_jre.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/java_buildpack/jre/zing_jre.rb b/lib/java_buildpack/jre/zing_jre.rb index 6f8d248757..4022ee7ac0 100755 --- a/lib/java_buildpack/jre/zing_jre.rb +++ b/lib/java_buildpack/jre/zing_jre.rb @@ -26,6 +26,7 @@ module Jre class ZingJRE < OpenJDKLike # (see JavaBuildpack::Component::ModularComponent#command) def command + # no command end # (see JavaBuildpack::Component::ModularComponent#sub_components) From d0067667ffcced8803c4e2dc6a29e20cb48a651a Mon Sep 17 00:00:00 2001 From: Brayan Henao Date: Wed, 12 Apr 2023 17:15:56 -0400 Subject: [PATCH 729/812] Install bootstrapped Ruby into java-buildpack specific location --- bin/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/run b/bin/run index 0782066a27..721c99e87d 100755 --- a/bin/run +++ b/bin/run @@ -7,7 +7,7 @@ set -o pipefail BUILDPACK_DIR="$(cd "$(dirname "${0}")/.." && pwd)" readonly BUILDPACK_DIR -RUBY_DIR="/tmp/ruby" +RUBY_DIR="/tmp/java-buildpack/ruby" readonly RUBY_DIR function util::config::lookup() { From b44919f0ee40325a854949d459cf4d742652f4de Mon Sep 17 00:00:00 2001 From: Rene Bamberger Date: Wed, 19 Apr 2023 09:26:25 +0200 Subject: [PATCH 730/812] special handling for token removed --- lib/java_buildpack/util/sanitizer.rb | 13 ++----------- spec/java_buildpack/util/sanitize_spec.rb | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index eafb4729b7..6f1f5de2df 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -36,17 +36,8 @@ def handle_params(params) query_params = '' - params.each do |key, value| - match = key.match(keywords) - - if match - params[key] = if match[0] == 'Api-Token' && value =~ /dt\w*/ - value.gsub(/(dt\w*\.\w*)\.\w*/, '\1.REDACTED') - else - '***' - end - end - + params.each do |key, _| + params[key] = '***' if key.match(keywords) query_params += key + '=' + params[key] + '&' end diff --git a/spec/java_buildpack/util/sanitize_spec.rb b/spec/java_buildpack/util/sanitize_spec.rb index 59609ea91d..f7c929a48f 100644 --- a/spec/java_buildpack/util/sanitize_spec.rb +++ b/spec/java_buildpack/util/sanitize_spec.rb @@ -37,7 +37,7 @@ '&password=***'\ '&include=java'\ '&bitness=64'\ - '&Api-Token=dt0c01.H67ALCXCXK7PWAAOQLENSRET.REDACTED'\ + '&Api-Token=***'\ '&secret-token=***'\ '&token=***') end From 2ad72330ce95021030244554d3f6b0070c77b200 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Mon, 24 Apr 2023 14:23:09 +0100 Subject: [PATCH 731/812] Updates release notes for JDK & MariaDB --- config/packaging.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index e6bcf61337..f6fdf60760 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -92,18 +92,18 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u362/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u372/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.18/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.19/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.6/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.7/)' jrebel_agent: name: JRebel Agent @@ -130,7 +130,7 @@ luna_security_provider: maria_db_jdbc: name: MariaDB JDBC Driver - release_notes: '[Release Notes](https://mariadb.com/kb/en/mariadb-connector-j-274-release-notes/)' + release_notes: '[Release Notes](https://mariadb.com/kb/en/mariadb-connector-j-2-7-9-release-notes/)' memory_calculator: name: Memory Calculator From 31c44864e5ee4ed234a7c90e9b83c0105e907806 Mon Sep 17 00:00:00 2001 From: Tyler Howard Date: Fri, 28 Apr 2023 13:54:56 -0400 Subject: [PATCH 732/812] Update Contrast Agent Version to 5.0 --- config/contrast_security_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index d7615bc680..9d45b2c2d9 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -15,5 +15,5 @@ # Configuration for the ContrastSecurity framework --- -version: 4.+ +version: 5.+ repository_root: https://download.run.pivotal.io/contrast-security From c455f273a185a9de324e6026e5ef782403a5b786 Mon Sep 17 00:00:00 2001 From: Stefan Mayr Date: Thu, 25 May 2023 00:37:40 +0200 Subject: [PATCH 733/812] Check for credentials keys as logical OR Fix check for credential keys: was connection_string AND instrumentation_key instead of logical OR --- .../framework/azure_application_insights_agent.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/azure_application_insights_agent.rb b/lib/java_buildpack/framework/azure_application_insights_agent.rb index 474e43f317..47b6d14c80 100644 --- a/lib/java_buildpack/framework/azure_application_insights_agent.rb +++ b/lib/java_buildpack/framework/azure_application_insights_agent.rb @@ -33,7 +33,7 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, CONNECTION_STRING, INSTRUMENTATION_KEY)['credentials'] + credentials = @application.services.find_service(FILTER, [CONNECTION_STRING, INSTRUMENTATION_KEY])['credentials'] if credentials.key?(CONNECTION_STRING) @droplet.java_opts.add_system_property('applicationinsights.connection.string', @@ -54,7 +54,7 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @application.services.one_service?(FILTER, CONNECTION_STRING, INSTRUMENTATION_KEY) + @application.services.one_service?(FILTER, [CONNECTION_STRING, INSTRUMENTATION_KEY]) end FILTER = /azure-application-insights/.freeze From fd68ad34ef8ba5c79e2ca755c5cef252a570e75c Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Fri, 26 May 2023 12:14:36 +0100 Subject: [PATCH 734/812] Polishing for Azure App Insights testing & Rubocop --- .../framework/azure_application_insights_agent.rb | 3 ++- .../framework/azure_application_insights_agent_spec.rb | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/java_buildpack/framework/azure_application_insights_agent.rb b/lib/java_buildpack/framework/azure_application_insights_agent.rb index 47b6d14c80..7ee630fe8f 100644 --- a/lib/java_buildpack/framework/azure_application_insights_agent.rb +++ b/lib/java_buildpack/framework/azure_application_insights_agent.rb @@ -33,7 +33,8 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release - credentials = @application.services.find_service(FILTER, [CONNECTION_STRING, INSTRUMENTATION_KEY])['credentials'] + credentials = @application.services.find_service(FILTER, [CONNECTION_STRING, + INSTRUMENTATION_KEY])['credentials'] if credentials.key?(CONNECTION_STRING) @droplet.java_opts.add_system_property('applicationinsights.connection.string', diff --git a/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb b/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb index c68d1933d9..06b2a957f4 100644 --- a/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb +++ b/spec/java_buildpack/framework/azure_application_insights_agent_spec.rb @@ -34,8 +34,7 @@ before do allow(services).to receive(:one_service?).with(/azure-application-insights/, - 'connection_string', - 'instrumentation_key') + %w[connection_string instrumentation_key]) .and_return(true) end From 7e2a7b9c9cd954838262b968d4b8efce15f78449 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Tue, 13 Jun 2023 14:14:09 +0100 Subject: [PATCH 735/812] Updates JProfiler to 13.x line --- config/jprofiler_profiler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/jprofiler_profiler.yml b/config/jprofiler_profiler.yml index ad07cf4281..d741f2f611 100644 --- a/config/jprofiler_profiler.yml +++ b/config/jprofiler_profiler.yml @@ -15,7 +15,7 @@ # JMX configuration --- -version: 12.+ +version: 13.+ repository_root: https://download.run.pivotal.io/jprofiler enabled: false nowait: true From 63c8d1e146af4a2b009e987977c4aca7fcdc500f Mon Sep 17 00:00:00 2001 From: M-Tsur Date: Tue, 13 Jun 2023 21:59:11 -0400 Subject: [PATCH 736/812] Add Takipi agent mandatory JVM arguments if Java is 9+ --- lib/java_buildpack/framework/takipi_agent.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index 4199455940..4cbad1cf4c 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -39,6 +39,8 @@ def release .add_agentpath(agent) .add_system_property('takipi.name', application_name) + update_java9 + @droplet.environment_variables .add_environment_variable('LD_LIBRARY_PATH', "$LD_LIBRARY_PATH:#{qualify_path(lib, @droplet.root)}") @@ -99,6 +101,14 @@ def node_name "#{@configuration['node_name_prefix']}-$CF_INSTANCE_INDEX" end + def update_java9 + return unless @droplet.java_home.java_9_or_later? + + @droplet.java_opts + .add_system_property('-Xshare:off') + .add_system_property('-XX:-UseTypeSpeculation') + end + end end From b9397797198e2ce45f438de7f0bc6f506f3ff01e Mon Sep 17 00:00:00 2001 From: M-Tsur Date: Tue, 13 Jun 2023 17:07:10 -0400 Subject: [PATCH 737/812] Add a documentation note about the injected JVM arguments on Java 9+ --- docs/framework-takipi_agent.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/framework-takipi_agent.md b/docs/framework-takipi_agent.md index a4a9384f25..b447393671 100644 --- a/docs/framework-takipi_agent.md +++ b/docs/framework-takipi_agent.md @@ -36,6 +36,15 @@ The framework can be configured by modifying the [`config/takipi_agent.yml`][] f | `node_name_prefix` | Node name prefix, will be concatenated with `-` and instance index | `application_name` | Override the CloudFoundry default application name +### Remarks +In case **Java 9+** is being used, 2 JVM flags will be added to the execution: +| Name | Description +| ---- | ----------- +| `-XX:-UseTypeSpeculation` | Disable type speculation optimization of the JVM which might not work properly in some situations where an agent is present. +| `-Xshare:off` | Disable class sharing as it might affect the agent's bytecode manipulation work. + +These two flags are needs as otherwise the agent or the JVM might not work properly together. + ## Logs Currently, you can get the Takipi agent logs using `cf files` command: From bdef75dfaaec31c442f3dbb75768ba8665d35d6c Mon Sep 17 00:00:00 2001 From: M-Tsur Date: Tue, 13 Jun 2023 23:19:43 -0400 Subject: [PATCH 738/812] Add JVM flags using the preformatted option instead of as system property --- lib/java_buildpack/framework/takipi_agent.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index 4cbad1cf4c..e9fc97ad56 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -105,8 +105,8 @@ def update_java9 return unless @droplet.java_home.java_9_or_later? @droplet.java_opts - .add_system_property('-Xshare:off') - .add_system_property('-XX:-UseTypeSpeculation') + .add_preformatted_options('-Xshare:off') + .add_preformatted_options('-XX:-UseTypeSpeculation') end end From 76e636c02946f41d817d17b3d3f35239f222dad8 Mon Sep 17 00:00:00 2001 From: M-Tsur Date: Tue, 13 Jun 2023 22:36:51 -0400 Subject: [PATCH 739/812] Create Takipi Agent logs folder during compile phase --- lib/java_buildpack/framework/takipi_agent.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/java_buildpack/framework/takipi_agent.rb b/lib/java_buildpack/framework/takipi_agent.rb index e9fc97ad56..ceeae84b97 100644 --- a/lib/java_buildpack/framework/takipi_agent.rb +++ b/lib/java_buildpack/framework/takipi_agent.rb @@ -31,6 +31,7 @@ class TakipiAgent < JavaBuildpack::Component::VersionedDependencyComponent def compile download_tar @droplet.copy_resources + FileUtils.mkdir_p @droplet.sandbox + 'log/agents/' end # (see JavaBuildpack::Component::BaseComponent#release) From 1466ed868a8cd1ed6ec93b59719c7c5f6f937220 Mon Sep 17 00:00:00 2001 From: M-Tsur Date: Wed, 14 Jun 2023 10:01:14 -0400 Subject: [PATCH 740/812] Update log viewing instructions according to review --- docs/framework-takipi_agent.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/framework-takipi_agent.md b/docs/framework-takipi_agent.md index b447393671..c14805f1be 100644 --- a/docs/framework-takipi_agent.md +++ b/docs/framework-takipi_agent.md @@ -47,9 +47,10 @@ These two flags are needs as otherwise the agent or the JVM might not work prope ## Logs -Currently, you can get the Takipi agent logs using `cf files` command: +Currently, you can view the Takipi agent logs using the `cf ssh` command: ``` -cf files app_name app/.java-buildpack/takipi_agent/log/ +cf ssh app_name +cat ~/app/.java-buildpack/takipi_agent/log/agents/*.log ``` ## Troubleshooting From 5b4136c2800fa790208ad001633427f4e5989616 Mon Sep 17 00:00:00 2001 From: David Sabeti Date: Fri, 2 Jun 2023 22:44:26 +0000 Subject: [PATCH 741/812] Install ruby when custom stacks are used --- bin/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/run b/bin/run index 721c99e87d..06d9b97a8b 100755 --- a/bin/run +++ b/bin/run @@ -93,7 +93,7 @@ function main() { local phase phase="$(basename "${0}")" - if [[ "${CF_STACK:-}" == "cflinuxfs4" ]]; then + if [[ "${CF_STACK:-}" != "cflinuxfs3" ]]; then if ! which ruby > /dev/null; then mkdir -p "${RUBY_DIR}" From fe9f6d232ea0fbb6ecb6b6fe66539ef8147dfcc6 Mon Sep 17 00:00:00 2001 From: David Sabeti Date: Tue, 20 Jun 2023 22:26:39 +0000 Subject: [PATCH 742/812] Install ruby whenever it isn't already present --- bin/run | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/bin/run b/bin/run index 06d9b97a8b..dc6220f0f1 100755 --- a/bin/run +++ b/bin/run @@ -93,16 +93,14 @@ function main() { local phase phase="$(basename "${0}")" - if [[ "${CF_STACK:-}" != "cflinuxfs3" ]]; then - if ! which ruby > /dev/null; then - mkdir -p "${RUBY_DIR}" - - util::install - fi + if ! which ruby > /dev/null; then + mkdir -p "${RUBY_DIR}" + util::install util::environment::setup fi + exec "${BUILDPACK_DIR}/bin/ruby-run" "${phase}" "${@-}" } From fcc977dca0736cd157e8b83a94248cc1a5e79250 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 22 Jun 2023 13:11:01 +0100 Subject: [PATCH 743/812] Updates repository location for AppD --- config/app_dynamics_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app_dynamics_agent.yml b/config/app_dynamics_agent.yml index c898bcdfef..3c55e187a6 100644 --- a/config/app_dynamics_agent.yml +++ b/config/app_dynamics_agent.yml @@ -16,7 +16,7 @@ # Configuration for the AppDynamics framework --- version: + -repository_root: https://packages.appdynamics.com/java +repository_root: "{default.repository.root}/appdynamics" default_application_name: $(jq -r -n "$VCAP_APPLICATION | .space_name + \":\" + .application_name | @sh") default_node_name: $(jq -r -n "\"$APPD_CF_NODE_PREFIX\" + ($VCAP_APPLICATION | .application_name) + \":$CF_INSTANCE_INDEX\" | @sh") default_tier_name: From 12724dd143fdb17fcab1c600c80cb0b328c39a41 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Fri, 7 Jul 2023 12:39:15 +0100 Subject: [PATCH 744/812] Updates Stackdriver Debugger to 3.x line, before deprecation --- config/google_stackdriver_debugger.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/google_stackdriver_debugger.yml b/config/google_stackdriver_debugger.yml index 8c4a521661..d1df043d71 100644 --- a/config/google_stackdriver_debugger.yml +++ b/config/google_stackdriver_debugger.yml @@ -15,7 +15,7 @@ # Configuration for the Groovy container --- -version: 2.+ +version: 3.+ repository_root: "{default.repository.root}/google-stackdriver-debugger/{platform}/{architecture}" application_name: application_version: From fcf4c38b41ac99d4761da5f38bb38db6a1340f70 Mon Sep 17 00:00:00 2001 From: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> Date: Fri, 7 Jul 2023 15:52:11 +0100 Subject: [PATCH 745/812] Revert "Updates Stackdriver Debugger to 3.x line, before deprecation" --- config/google_stackdriver_debugger.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/google_stackdriver_debugger.yml b/config/google_stackdriver_debugger.yml index d1df043d71..8c4a521661 100644 --- a/config/google_stackdriver_debugger.yml +++ b/config/google_stackdriver_debugger.yml @@ -15,7 +15,7 @@ # Configuration for the Groovy container --- -version: 3.+ +version: 2.+ repository_root: "{default.repository.root}/google-stackdriver-debugger/{platform}/{architecture}" application_name: application_version: From 01901e074371c3e34b18620ddad5069235a3d2fd Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 2 Aug 2023 14:57:18 +0100 Subject: [PATCH 746/812] disables Google Stackdriver framework --- config/components.yml | 2 +- config/packaging.yml | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/config/components.yml b/config/components.yml index 475a03c8c0..41d7bc1b73 100644 --- a/config/components.yml +++ b/config/components.yml @@ -54,7 +54,7 @@ frameworks: - "JavaBuildpack::Framework::Debug" - "JavaBuildpack::Framework::DynatraceOneAgent" - "JavaBuildpack::Framework::ElasticApmAgent" - - "JavaBuildpack::Framework::GoogleStackdriverDebugger" +# - "JavaBuildpack::Framework::GoogleStackdriverDebugger" - "JavaBuildpack::Framework::GoogleStackdriverProfiler" - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::JacocoAgent" diff --git a/config/packaging.yml b/config/packaging.yml index f6fdf60760..aed29fdc22 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -67,10 +67,6 @@ elastic_apm_agent: geode_store: name: Geode Tomcat Session Store -google_stackdriver_debugger: - name: Google Stackdriver Debugger - release_notes: '[Release Notes](https://cloud.google.com/debugger/docs/release-notes)' - google_stackdriver_profiler: name: Google Stackdriver Profiler release_notes: '[Release Notes](https://cloud.google.com/profiler/docs/release-notes)' @@ -92,18 +88,18 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-8u372/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u382b6/general/release-notes/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-11.0.19/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.20b8/general/release-notes/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://bell-sw.com/pages/liberica-release-notes-17.0.7/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.8b7/general/release-notes/)' jrebel_agent: name: JRebel Agent @@ -191,4 +187,4 @@ tomcat: your_kit_profiler: name: YourKit Profiler - release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2022_3_builds.jsp)' + release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2023_5_builds.jsp)' From 39802b1c5ac5ea0c1cf46a42fd3efbddd44725aa Mon Sep 17 00:00:00 2001 From: Ben Ross Date: Fri, 4 Aug 2023 10:45:30 -0700 Subject: [PATCH 747/812] Update geode-store for compatibility with Gemfire 9.15.6 --- config/tomcat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tomcat.yml b/config/tomcat.yml index d6c1a2ac61..c05fcdeb09 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -42,5 +42,5 @@ redis_store: geode_store: # The version of Geode Store must be less than or equal to your Tanzu Gemfire for VMs version to ensure compatibility. # The Geode Store version is pinned to 1.12.4 to be compatible with the most commonly used versions of Tanzu Gemfire for VMs. - version: 1.13.7 + version: 1.14.9 repository_root: https://java-buildpack-tomcat-gemfire-store.s3-us-west-2.amazonaws.com From e602344ae016b9edcc48f0c865c9e6e6ef2f2d43 Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Tue, 22 Aug 2023 20:57:28 -0400 Subject: [PATCH 748/812] Fix documentation * add precision over the bin scripts detection --- docs/container-dist_zip.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/container-dist_zip.md b/docs/container-dist_zip.md index 67456753c5..aadd126a96 100644 --- a/docs/container-dist_zip.md +++ b/docs/container-dist_zip.md @@ -5,13 +5,13 @@ The Dist Zip Container allows applications packaged in [`distZip`-style][] to be Detection Criteria
    -
  • A start script in the bin/ subdirectory of the application directory or one of its immediate subdirectories (but not in both), and
  • -
  • A JAR file in the lib/ subdirectory of the application directory or one of its immediate subdirectories (but not in both)
  • +
  • A start script in the bin/ subdirectory of the application directory or one of its immediate subdirectories (but not in both) - for example, a bin folder with: bin/myscript along with bin/myscript.bat, and
  • +
  • A JAR file in the lib/ subdirectory of the application directory or one of its immediate subdirectories (but not in both)
Tags - dist-zip + dist-zip Tags are printed to standard output by the buildpack detect script From b175126947fa00f2946545770188e3ad3bb2f20a Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Tue, 22 Aug 2023 15:52:40 -0400 Subject: [PATCH 749/812] Fix #1027: properly detect new mysql connector * Mysql connector was renamed recently from mysql-connector-java to mysql-connector-j, and needs to be detected by the buildpack * Rephrase documentation to make it more obvious that if a maria db client or mysql connector exist, the buildpack should not add its own mariadb connector --- docs/framework-maria_db_jdbc.md | 12 ++++++------ lib/java_buildpack/framework/maria_db_jdbc.rb | 2 +- .../WEB-INF/lib/mysql-connector-j-8.0.33.jar | 0 spec/java_buildpack/framework/maria_db_jdbc_spec.rb | 6 ++++++ 4 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 spec/fixtures/framework_mariadb_jdbc_with_new_mysql_driver/WEB-INF/lib/mysql-connector-j-8.0.33.jar diff --git a/docs/framework-maria_db_jdbc.md b/docs/framework-maria_db_jdbc.md index 5e146253a8..635767f92f 100644 --- a/docs/framework-maria_db_jdbc.md +++ b/docs/framework-maria_db_jdbc.md @@ -4,18 +4,18 @@ The MariaDB JDBC Framework causes a JDBC driver JAR to be automatically download - - +
Detection CriterionExistence of a single bound MariaDB or MySQL service and no provided MariaDB or MySQL JDBC JAR. + Existence of a single bound MariaDB or MySQL service and NO provided MariaDB or MySQL JDBC jar.
    -
  • Existence of a MariaDB service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has mariadb as a substring.
  • -
  • Existence of a MySQL service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has mysql as a substring.
  • -
  • Existence of a MariaDB JDBC JAR is defined as the application containing a JAR who's name matches mariadb-java-client*.jar
  • -
  • Existence of a MySQL JDBC JAR is defined as the application containing a JAR who's name matches mysql-connector-java*.jar
  • +
  • Existence of a MariaDB service is defined as the VCAP_SERVICES payload containing a service whose name, label or tag has mariadb as a substring.
  • +
  • Existence of a MySQL service is defined as the VCAP_SERVICES payload containing a service whose name, label or tag has mysql as a substring.
  • +
  • Existence of a MariaDB JDBC jar is defined as the application containing a JAR whose name matches mariadb-java-client*.jar
  • +
  • Existence of a MySQL JDBC jar is defined as the application containing a JAR whose name matches mysql-connector-j*.jar
Tagsmaria-db-jdbc=<version>maria-db-jdbc=<version>
Tags are printed to standard output by the buildpack detect script diff --git a/lib/java_buildpack/framework/maria_db_jdbc.rb b/lib/java_buildpack/framework/maria_db_jdbc.rb index 628010d1e7..712b367804 100644 --- a/lib/java_buildpack/framework/maria_db_jdbc.rb +++ b/lib/java_buildpack/framework/maria_db_jdbc.rb @@ -46,7 +46,7 @@ def supports? private def driver? - %w[mariadb-java-client*.jar mysql-connector-java*.jar].any? do |candidate| + %w[mariadb-java-client*.jar mysql-connector-j*.jar].any? do |candidate| (@application.root + '**' + candidate).glob.any? end end diff --git a/spec/fixtures/framework_mariadb_jdbc_with_new_mysql_driver/WEB-INF/lib/mysql-connector-j-8.0.33.jar b/spec/fixtures/framework_mariadb_jdbc_with_new_mysql_driver/WEB-INF/lib/mysql-connector-j-8.0.33.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/maria_db_jdbc_spec.rb b/spec/java_buildpack/framework/maria_db_jdbc_spec.rb index a3ce5aad26..0ecdc315da 100644 --- a/spec/java_buildpack/framework/maria_db_jdbc_spec.rb +++ b/spec/java_buildpack/framework/maria_db_jdbc_spec.rb @@ -49,6 +49,12 @@ expect(component.detect).to be_nil end + it 'does not detect if the application has a new style -j MySQL driver', + app_fixture: 'framework_mariadb_jdbc_with_new_mysql_driver' do + + expect(component.detect).to be_nil + end + it 'downloads the MariaDB driver when needed', cache_fixture: 'stub-mariadb-java-client.jar' do From ddaa8564470aea1b7143a57c53f6809786fc49ec Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 16 Aug 2023 17:22:14 +0100 Subject: [PATCH 750/812] adds java-cfenv framework --- README.md | 1 + config/components.yml | 3 +- config/java_cf_env.yml | 22 +++++ config/packaging.yml | 4 + docs/framework-java-cfenv.md | 19 ++++ lib/java_buildpack/framework/java_cf_env.rb | 67 ++++++++++++++ .../framework/spring_auto_reconfiguration.rb | 5 +- .../WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar | 0 .../META-INF/MANIFEST.MF | 3 + .../WEB-INF/lib/spring-boot-1.0.0.RELEASE.jar | 0 .../META-INF/MANIFEST.MF | 3 + .../WEB-INF/lib/spring-boot-3.0.0.M1.jar | 0 .../META-INF/MANIFEST.MF | 4 + .../WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar | 0 .../lib/java-cfenv-boot-2.1.2.RELEASE.jar | 0 .../lib/java-cfenv-jdbc-2.1.2.RELEASE.jar | 0 .../WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar | 0 spec/fixtures/stub-java-cfenv.jar | Bin 0 -> 341 bytes .../framework/java_cfenv_spec.rb | 84 ++++++++++++++++++ .../spring_auto_reconfiguration_spec.rb | 8 +- 20 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 config/java_cf_env.yml create mode 100644 docs/framework-java-cfenv.md create mode 100644 lib/java_buildpack/framework/java_cf_env.rb create mode 100644 spec/fixtures/framework_auto_reconfiguration_java_cfenv_bp/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar create mode 100644 spec/fixtures/framework_java_cf_boot_2/META-INF/MANIFEST.MF create mode 100644 spec/fixtures/framework_java_cf_boot_2/WEB-INF/lib/spring-boot-1.0.0.RELEASE.jar create mode 100644 spec/fixtures/framework_java_cf_boot_3/META-INF/MANIFEST.MF create mode 100644 spec/fixtures/framework_java_cf_boot_3/WEB-INF/lib/spring-boot-3.0.0.M1.jar create mode 100644 spec/fixtures/framework_java_cf_exists/META-INF/MANIFEST.MF create mode 100644 spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar create mode 100644 spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-boot-2.1.2.RELEASE.jar create mode 100644 spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-jdbc-2.1.2.RELEASE.jar create mode 100644 spec/fixtures/framework_java_cf_exists/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar create mode 100644 spec/fixtures/stub-java-cfenv.jar create mode 100644 spec/java_buildpack/framework/java_cfenv_spec.rb diff --git a/README.md b/README.md index e563ea745d..e562ea1a34 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ The buildpack supports extension through the use of Git repository forking. The * [Google Stackdriver Profiler](docs/framework-google_stackdriver_profiler.md) ([Configuration](docs/framework-google_stackdriver_profiler.md#configuration)) * [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration)) * [JaCoCo Agent](docs/framework-jacoco_agent.md) ([Configuration](docs/framework-jacoco_agent.md#configuration)) + * [Java CfEnv](docs/framework-java-cfenv.md) ([Configuration](docs/framework-java-cfenv.md#configuration)) * [Java Memory Assistant](docs/framework-java_memory_assistant.md) ([Configuration](docs/framework-java_memory_assistant.md#configuration)) * [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration)) * [JProfiler Profiler](docs/framework-jprofiler_profiler.md) ([Configuration](docs/framework-jprofiler_profiler.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 41d7bc1b73..79a60156fd 100644 --- a/config/components.yml +++ b/config/components.yml @@ -54,10 +54,11 @@ frameworks: - "JavaBuildpack::Framework::Debug" - "JavaBuildpack::Framework::DynatraceOneAgent" - "JavaBuildpack::Framework::ElasticApmAgent" -# - "JavaBuildpack::Framework::GoogleStackdriverDebugger" +# - "JavaBuildpack::Framework::GoogleStackdriverDebugger" - "JavaBuildpack::Framework::GoogleStackdriverProfiler" - "JavaBuildpack::Framework::IntroscopeAgent" - "JavaBuildpack::Framework::JacocoAgent" + - "JavaBuildpack::Framework::JavaCfEnv" - "JavaBuildpack::Framework::JavaMemoryAssistant" - "JavaBuildpack::Framework::Jmx" - "JavaBuildpack::Framework::JprofilerProfiler" diff --git a/config/java_cf_env.yml b/config/java_cf_env.yml new file mode 100644 index 0000000000..e0494369c8 --- /dev/null +++ b/config/java_cf_env.yml @@ -0,0 +1,22 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2023 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the Spring Auto Reconfiguration framework. +# Note that the repository is shared with the Play Auto Reconfiguration framework and should be kept in step to +# avoid conflicts. +--- +version: 3.+ +repository_root: "{default.repository.root}/java-cfenv" +enabled: true diff --git a/config/packaging.yml b/config/packaging.yml index aed29fdc22..8818f0c517 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -82,6 +82,10 @@ jacoco_agent: name: JaCoCo Agent release_notes: '[Release Notes](https://github.com/jacoco/jacoco/releases)' +java_cf_env: + name: Java CFEnv + release_notes: '[Release Notes](https://github.com/pivotal-cf/java-cfenv/releases)' + jprofiler_profiler: name: JProfiler Profiler release_notes: '[ChangeLog](https://www.ej-technologies.com/download/jprofiler/changelog.html)' diff --git a/docs/framework-java-cfenv.md b/docs/framework-java-cfenv.md new file mode 100644 index 0000000000..1e1fe474a7 --- /dev/null +++ b/docs/framework-java-cfenv.md @@ -0,0 +1,19 @@ +# Java CfEnv Framework +The Java CfEnv Framework provides the `java-cfenv` library for Spring Boot 3+ applications. This library sets various Spring Boot properties by parsing CloudFoundry variables such as `VCAP_SERVICES`, allowing Spring Boot's autoconfiguration to kick in. + +This is the recommended replacement for Spring AutoReconfiguration library which is deprecated. See the `java-cfenv` repostitory for more detail. + +It also sets the 'cloud' profile for Spring Boot applications, as the Spring AutoReconfiguration framework did. + + + + + + + + + + + +
Detection CriterionExistence of a spring-boot-3*.jar file in the application directory or a `Spring-Boot-Version: 3.*` manifest entryNo existing `java-cfenv` library found
Tagsjava-cf-env=<version>
+Tags are printed to standard output by the buildpack detect script diff --git a/lib/java_buildpack/framework/java_cf_env.rb b/lib/java_buildpack/framework/java_cf_env.rb new file mode 100644 index 0000000000..b89c913a07 --- /dev/null +++ b/lib/java_buildpack/framework/java_cf_env.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' +require 'java_buildpack/util/spring_boot_utils' + +module JavaBuildpack + module Framework + + # Encapsulates the detect, compile, and release functionality for enabling cloud auto-reconfiguration in Spring + # applications. + class JavaCfEnv < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + def initialize(context) + @spring_boot_utils = JavaBuildpack::Util::SpringBootUtils.new + super(context) + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.additional_libraries << (@droplet.sandbox + jar_name) + @droplet.environment_variables.add_environment_variable 'SPRING_PROFILES_INCLUDE', 'cloud' + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @configuration['enabled'] && spring_boot_3? && !java_cfenv? + end + + private + + def spring_boot_3? + @spring_boot_utils.is?(@application) && Gem::Version.new((@spring_boot_utils.version @application)).release >= + Gem::Version.new('3.0.0') + end + + def java_cfenv? + (@droplet.root + '**/*java-cfenv*.jar').glob.any? + end + + end + end +end diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index 80b20ca027..ece570f3f9 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -59,7 +59,10 @@ def spring? end def java_cfenv? - (@droplet.root + '**/*java-cfenv*.jar').glob.any? + (@droplet.root + '**/*java-cfenv*.jar').glob.any? || + @droplet.additional_libraries.sort.map do |additional_library| + return false unless (additional_library.dirname + '*java-cfenv*.jar').glob.any? + end end def spring_cloud_connectors? diff --git a/spec/fixtures/framework_auto_reconfiguration_java_cfenv_bp/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar b/spec/fixtures/framework_auto_reconfiguration_java_cfenv_bp/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_java_cf_boot_2/META-INF/MANIFEST.MF b/spec/fixtures/framework_java_cf_boot_2/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..ce0077f4ce --- /dev/null +++ b/spec/fixtures/framework_java_cf_boot_2/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Spring-Boot-Lib: manifest-lib-value/ +Main-Class: org.springframework.boot.loader.JarLauncher +Spring-Boot-Version: 2.1.0.RELEASE diff --git a/spec/fixtures/framework_java_cf_boot_2/WEB-INF/lib/spring-boot-1.0.0.RELEASE.jar b/spec/fixtures/framework_java_cf_boot_2/WEB-INF/lib/spring-boot-1.0.0.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_java_cf_boot_3/META-INF/MANIFEST.MF b/spec/fixtures/framework_java_cf_boot_3/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..a64827339d --- /dev/null +++ b/spec/fixtures/framework_java_cf_boot_3/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Spring-Boot-Lib: manifest-lib-value/ +Main-Class: org.springframework.boot.loader.JarLauncher +Spring-Boot-Version: 3.0.0.M1 diff --git a/spec/fixtures/framework_java_cf_boot_3/WEB-INF/lib/spring-boot-3.0.0.M1.jar b/spec/fixtures/framework_java_cf_boot_3/WEB-INF/lib/spring-boot-3.0.0.M1.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_java_cf_exists/META-INF/MANIFEST.MF b/spec/fixtures/framework_java_cf_exists/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..47eb0c27e7 --- /dev/null +++ b/spec/fixtures/framework_java_cf_exists/META-INF/MANIFEST.MF @@ -0,0 +1,4 @@ +Spring-Boot-Lib: manifest-lib-value/ +Spring-Boot-Version: 3.2.5.RELEASE +Main-Class: org.springframework.boot.loader.JarLauncher + diff --git a/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar b/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-boot-2.1.2.RELEASE.jar b/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-boot-2.1.2.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-jdbc-2.1.2.RELEASE.jar b/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-jdbc-2.1.2.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar b/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/stub-java-cfenv.jar b/spec/fixtures/stub-java-cfenv.jar new file mode 100644 index 0000000000000000000000000000000000000000..0878c3ccb50e0696f38ae356e9854c75199158f3 GIT binary patch literal 341 zcmWIWW@Zs#;Nak3$ZLM$#DD}i8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1gx0>v$BCyF#%yMkUj+BFaQAGLPY%l literal 0 HcmV?d00001 diff --git a/spec/java_buildpack/framework/java_cfenv_spec.rb b/spec/java_buildpack/framework/java_cfenv_spec.rb new file mode 100644 index 0000000000..e06dc4fbbf --- /dev/null +++ b/spec/java_buildpack/framework/java_cfenv_spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'logging_helper' +require 'java_buildpack/framework/java_cf_env' + +describe JavaBuildpack::Framework::JavaCfEnv do + include_context 'with component help' + include_context 'with console help' + include_context 'with logging help' + + let(:configuration) { { 'enabled' => true } } + + it 'detects with Spring Boot 3 JAR', + app_fixture: 'framework_java_cf_boot_3' do + + expect(component.detect).to eq("java-cf-env=#{version}") + end + + it 'does not detect with Spring Boot < 3', + app_fixture: 'framework_java_cf_boot_2' do + + expect(component.detect).to be_nil + end + + it 'does not detect with Spring Boot 3 & java-cfenv present', + app_fixture: 'framework_java_cf_exists' do + + expect(component.detect).to be_nil + end + + context do + let(:configuration) { { 'enabled' => false } } + + it 'does not detect if disabled', + app_fixture: 'framework_java_cf_boot_3' do + + expect(component.detect).to be_nil + end + end + + it 'downloads additional libraries', + app_fixture: 'framework_java_cf_boot_3', + cache_fixture: 'stub-java-cfenv.jar' do + + component.compile + + expect(sandbox + "java_cf_env-#{version}.jar").to exist + end + + it 'adds to additional libraries', + app_fixture: 'framework_java_cf_boot_3', + cache_fixture: 'stub-java-cfenv.jar' do + + component.release + + expect(additional_libraries).to include(sandbox + "java_cf_env-#{version}.jar") + end + + it 'activates the cloud profile', + app_fixture: 'framework_java_cf_boot_3', + cache_fixture: 'stub-java-cfenv.jar' do + + component.release + + expect(environment_variables).to include('SPRING_PROFILES_INCLUDE=cloud') + end +end diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index d3f5cec59c..672b53fd78 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -39,12 +39,18 @@ expect(component.detect).to eq("spring-auto-reconfiguration=#{version}") end - it 'does not detect with Spring JAR and java-cfenv', + it 'does not detect with Spring JAR and user java-cfenv', app_fixture: 'framework_auto_reconfiguration_java_cfenv' do expect(component.detect).to be_nil end + it 'does not detect with Spring JAR and buildpack java-cfenv', + app_fixture: 'framework_auto_reconfiguration_java_cfenv_bp' do + + expect(component.detect).to be_nil + end + it 'does not detect without Spring JAR' do expect(component.detect).to be_nil end From b0c4bfe02105eb61a7cfbbf30111399f55d8ef7e Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 30 Aug 2023 12:55:56 +0100 Subject: [PATCH 751/812] addresses comments on java-cfenv framework --- config/java_cf_env.yml | 6 +++--- lib/java_buildpack/framework/java_cf_env.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/java_cf_env.yml b/config/java_cf_env.yml index e0494369c8..a021138ff7 100644 --- a/config/java_cf_env.yml +++ b/config/java_cf_env.yml @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Configuration for the Spring Auto Reconfiguration framework. -# Note that the repository is shared with the Play Auto Reconfiguration framework and should be kept in step to -# avoid conflicts. +# Configuration for the Java CfEnv framework. +# See https://github.com/pivotal-cf/java-cfenv for library information + --- version: 3.+ repository_root: "{default.repository.root}/java-cfenv" diff --git a/lib/java_buildpack/framework/java_cf_env.rb b/lib/java_buildpack/framework/java_cf_env.rb index b89c913a07..5b78128fe8 100644 --- a/lib/java_buildpack/framework/java_cf_env.rb +++ b/lib/java_buildpack/framework/java_cf_env.rb @@ -48,7 +48,7 @@ def release # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) def supports? - @configuration['enabled'] && spring_boot_3? && !java_cfenv? + @configuration['enabled'] && spring_boot_3? && !java_cfenv? end private From 00238912f0cadce25b7c8211f2201e792360fbfd Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 6 Sep 2023 16:44:08 +0100 Subject: [PATCH 752/812] fixes bug with supports logic for cfenv --- .../framework/spring_auto_reconfiguration.rb | 7 +++--- .../WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar | 0 .../spring_auto_reconfiguration_spec.rb | 23 ++++++++++++++----- 3 files changed, 20 insertions(+), 10 deletions(-) delete mode 100644 spec/fixtures/framework_auto_reconfiguration_java_cfenv_bp/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index ece570f3f9..bbc2383b97 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -59,10 +59,9 @@ def spring? end def java_cfenv? - (@droplet.root + '**/*java-cfenv*.jar').glob.any? || - @droplet.additional_libraries.sort.map do |additional_library| - return false unless (additional_library.dirname + '*java-cfenv*.jar').glob.any? - end + (@droplet.root + '**/*java-cfenv*.jar').glob.any? || @droplet.additional_libraries.any? do |additional_library| + additional_library.instance_variable_get(:@pathname).fnmatch?('*java-cfenv*.jar') + end end def spring_cloud_connectors? diff --git a/spec/fixtures/framework_auto_reconfiguration_java_cfenv_bp/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar b/spec/fixtures/framework_auto_reconfiguration_java_cfenv_bp/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index 672b53fd78..b366130ee9 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -45,12 +45,6 @@ expect(component.detect).to be_nil end - it 'does not detect with Spring JAR and buildpack java-cfenv', - app_fixture: 'framework_auto_reconfiguration_java_cfenv_bp' do - - expect(component.detect).to be_nil - end - it 'does not detect without Spring JAR' do expect(component.detect).to be_nil end @@ -110,4 +104,21 @@ expect(additional_libraries).to include(sandbox + "spring_auto_reconfiguration-#{version}.jar") end + context('when java-cfenv injects its lib') do + + before do + additional_libraries.insert 0, additional_libs_directory + 'stub-java-cfenv.jar' + end + + after do + additional_libraries.delete additional_libs_directory + 'stub-java-cfenv.jar' + end + + it 'does not detect with Spring JAR and injected cfenv', + app_fixture: 'framework_auto_reconfiguration_servlet_3' do + + expect(component.detect).to be_nil + end + + end end From dbcaf77ac0ce1258927ffb67456fa276e7527325 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Fri, 8 Sep 2023 14:30:30 +0100 Subject: [PATCH 753/812] fixes bug with logic for SAR --- lib/java_buildpack/framework/java_cf_env.rb | 3 ++- .../framework/spring_auto_reconfiguration.rb | 11 +++++++++-- spec/java_buildpack/framework/java_cfenv_spec.rb | 2 +- .../framework/spring_auto_reconfiguration_spec.rb | 4 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/framework/java_cf_env.rb b/lib/java_buildpack/framework/java_cf_env.rb index 5b78128fe8..3335dfba50 100644 --- a/lib/java_buildpack/framework/java_cf_env.rb +++ b/lib/java_buildpack/framework/java_cf_env.rb @@ -41,7 +41,8 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.additional_libraries << (@droplet.sandbox + jar_name) - @droplet.environment_variables.add_environment_variable 'SPRING_PROFILES_INCLUDE', 'cloud' + @droplet.environment_variables.add_environment_variable \ + 'SPRING_PROFILES_INCLUDE', '$SPRING_PROFILES_INCLUDE,cloud' end protected diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb index bbc2383b97..f53646e240 100644 --- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb +++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb @@ -33,6 +33,7 @@ def initialize(context) # (see JavaBuildpack::Component::BaseComponent#compile) def compile log_warning_scc_manual if spring_cloud_connectors? + return if java_cf_env_framework? download_jar @droplet.additional_libraries << (@droplet.sandbox + jar_name) @@ -42,6 +43,8 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release + return if java_cf_env_framework? + @droplet.additional_libraries << (@droplet.sandbox + jar_name) end @@ -59,8 +62,12 @@ def spring? end def java_cfenv? - (@droplet.root + '**/*java-cfenv*.jar').glob.any? || @droplet.additional_libraries.any? do |additional_library| - additional_library.instance_variable_get(:@pathname).fnmatch?('*java-cfenv*.jar') + (@droplet.root + '**/*java-cfenv*.jar').glob.any? || java_cf_env_framework? + end + + def java_cf_env_framework? + @droplet.additional_libraries.any? do |additional_library| + additional_library.instance_variable_get(:@pathname).fnmatch?('*java_cf_env*.jar') end end diff --git a/spec/java_buildpack/framework/java_cfenv_spec.rb b/spec/java_buildpack/framework/java_cfenv_spec.rb index e06dc4fbbf..6e75a8145b 100644 --- a/spec/java_buildpack/framework/java_cfenv_spec.rb +++ b/spec/java_buildpack/framework/java_cfenv_spec.rb @@ -79,6 +79,6 @@ component.release - expect(environment_variables).to include('SPRING_PROFILES_INCLUDE=cloud') + expect(environment_variables).to include('SPRING_PROFILES_INCLUDE=$SPRING_PROFILES_INCLUDE,cloud') end end diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb index b366130ee9..17a2946b04 100644 --- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb +++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb @@ -107,11 +107,11 @@ context('when java-cfenv injects its lib') do before do - additional_libraries.insert 0, additional_libs_directory + 'stub-java-cfenv.jar' + additional_libraries.insert 0, additional_libs_directory + 'java_cf_env.jar' end after do - additional_libraries.delete additional_libs_directory + 'stub-java-cfenv.jar' + additional_libraries.delete additional_libs_directory + 'java_cf_env.jar' end it 'does not detect with Spring JAR and injected cfenv', From a58b76fa39e64756e328734022c0643ad2ebff7a Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Mon, 11 Sep 2023 14:44:27 -0400 Subject: [PATCH 754/812] Remove profile inclusion --- lib/java_buildpack/framework/java_cf_env.rb | 2 -- spec/java_buildpack/framework/java_cfenv_spec.rb | 8 -------- 2 files changed, 10 deletions(-) diff --git a/lib/java_buildpack/framework/java_cf_env.rb b/lib/java_buildpack/framework/java_cf_env.rb index 3335dfba50..3b3644a040 100644 --- a/lib/java_buildpack/framework/java_cf_env.rb +++ b/lib/java_buildpack/framework/java_cf_env.rb @@ -41,8 +41,6 @@ def compile # (see JavaBuildpack::Component::BaseComponent#release) def release @droplet.additional_libraries << (@droplet.sandbox + jar_name) - @droplet.environment_variables.add_environment_variable \ - 'SPRING_PROFILES_INCLUDE', '$SPRING_PROFILES_INCLUDE,cloud' end protected diff --git a/spec/java_buildpack/framework/java_cfenv_spec.rb b/spec/java_buildpack/framework/java_cfenv_spec.rb index 6e75a8145b..bfd67e7729 100644 --- a/spec/java_buildpack/framework/java_cfenv_spec.rb +++ b/spec/java_buildpack/framework/java_cfenv_spec.rb @@ -73,12 +73,4 @@ expect(additional_libraries).to include(sandbox + "java_cf_env-#{version}.jar") end - it 'activates the cloud profile', - app_fixture: 'framework_java_cf_boot_3', - cache_fixture: 'stub-java-cfenv.jar' do - - component.release - - expect(environment_variables).to include('SPRING_PROFILES_INCLUDE=$SPRING_PROFILES_INCLUDE,cloud') - end end From 366fbeba0e64d4fab647f22f73023666faa1d4c5 Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Tue, 27 Jun 2023 14:34:52 -0400 Subject: [PATCH 755/812] Add OpenTelemetry Javaagent framework This framework will wire up the OpenTelemetry Javaagent auto instrumentation. It leverages VCAP_SERVICES and the existence of a service binding with a specific name (`otel-collector`). --- config/components.yml | 1 + config/opentelemetry_javaagent.yml | 19 ++++++ docs/framework-opentelemetry_javaagent.md | 40 +++++++++++ .../framework/opentelemetry_javaagent.rb | 54 +++++++++++++++ .../framework/opentelemtry_javaagent_spec.rb | 66 +++++++++++++++++++ 5 files changed, 180 insertions(+) create mode 100644 config/opentelemetry_javaagent.yml create mode 100644 docs/framework-opentelemetry_javaagent.md create mode 100644 lib/java_buildpack/framework/opentelemetry_javaagent.rb create mode 100644 spec/java_buildpack/framework/opentelemtry_javaagent_spec.rb diff --git a/config/components.yml b/config/components.yml index 79a60156fd..90a12ec28e 100644 --- a/config/components.yml +++ b/config/components.yml @@ -67,6 +67,7 @@ frameworks: - "JavaBuildpack::Framework::MariaDbJDBC" - "JavaBuildpack::Framework::MetricWriter" - "JavaBuildpack::Framework::NewRelicAgent" + - "JavaBuildpack::Framework::OpenTelemetryJavaagent" - "JavaBuildpack::Framework::PostgresqlJDBC" - "JavaBuildpack::Framework::RiverbedAppinternalsAgent" - "JavaBuildpack::Framework::SealightsAgent" diff --git a/config/opentelemetry_javaagent.yml b/config/opentelemetry_javaagent.yml new file mode 100644 index 0000000000..2e45e5713e --- /dev/null +++ b/config/opentelemetry_javaagent.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2023 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Configuration for the OpenTelemetry Javaagent +--- +version: + +repository_root: https://raw.githubusercontent.com/open-telemetry/opentelemetry-java-instrumentation/cloudfoundry/ diff --git a/docs/framework-opentelemetry_javaagent.md b/docs/framework-opentelemetry_javaagent.md new file mode 100644 index 0000000000..b10a9455b5 --- /dev/null +++ b/docs/framework-opentelemetry_javaagent.md @@ -0,0 +1,40 @@ +# OpenTelemetry Javaagent + +The OpenTelemetry Javaagent buildpack framework will cause an application to be automatically instrumented +with the [OpenTelemetry Javaagent Instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation). + +Data will be sent directly to the OpenTelemetry Collector. + + + + + + + + + + +
Detection CriterionExistence of a bound service containing the string otel-collector
Tagsopentelemetry-javaagent=<version>
+ +Tags are printed to standard output by the buildpack detect script + +## User-Provided Service + +Users are currently expected to provide their own "custom user provided service" (cups) +instance and bind it to their application. The service MUST contain the string `otel-collector`. + +### Choosing a version + +Most users should skip this and simply use the latest version of the agent available (the default). +To override the default and choose a specific version, you can use the `JBP_CONFIG_*` mechanism +and set the `JBP_CONFIG_OPENTELEMETRY_JAVAAGENT` environment variable for your application. + +For example, to use version 1.27.0 of the OpenTelemetry Javaagent Instrumentation, you +could run: +``` +$ cf set-env testapp JBP_CONFIG_OPENTELEMETRY_JAVAAGENT '{version: 1.27.0}' +``` + +# Additional Resources + +* [OpenTelemetry Javaagent Instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation) on GitHub diff --git a/lib/java_buildpack/framework/opentelemetry_javaagent.rb b/lib/java_buildpack/framework/opentelemetry_javaagent.rb new file mode 100644 index 0000000000..bf28eb5941 --- /dev/null +++ b/lib/java_buildpack/framework/opentelemetry_javaagent.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2023 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/component/versioned_dependency_component' +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Main class for adding the OpenTelemetry Javaagent instrumentation + class OpenTelemetryJavaagent < JavaBuildpack::Component::VersionedDependencyComponent + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + java_opts = @droplet.java_opts + java_opts.add_javaagent(@droplet.sandbox + jar_name) + + # Set the otel.service.name to the application_name + app_name = @application.details['application_name'] + java_opts.add_system_property('otel.service.name', app_name) + end + + protected + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? REQUIRED_SERVICE_NAME_FILTER + end + + # bound service must contain the string `otel-collector` + REQUIRED_SERVICE_NAME_FILTER = /otel-collector/.freeze + + end + end +end diff --git a/spec/java_buildpack/framework/opentelemtry_javaagent_spec.rb b/spec/java_buildpack/framework/opentelemtry_javaagent_spec.rb new file mode 100644 index 0000000000..c1244ef4a7 --- /dev/null +++ b/spec/java_buildpack/framework/opentelemtry_javaagent_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/opentelemetry_javaagent' +require 'java_buildpack/util/tokenized_version' + +describe JavaBuildpack::Framework::OpenTelemetryJavaagent do + include_context 'with component help' + + let(:configuration) { { 'version' => '1.27.0' } } + let(:vcap_application) { { 'application_name' => 'GreatServiceTM' } } + + it 'does not detect without otel-collector service bind' do + expect(component.detect).to be_nil + end + + context 'when detected' do + + before do + allow(services).to receive(:one_service?).with(/otel-collector/).and_return(true) + end + + it 'detects with opentelemetry-javaagent' do + expect(component.detect).to eq("opentelemetry-javaagent=#{version}") + end + + it 'downloads the opentelemetry javaagent jar', cache_fixture: 'stub-download.jar' do + + component.compile + + expect(sandbox + "opentelemetry_javaagent-#{version}.jar").to exist + end + + it 'updates JAVA_OPTS' do + component.release + + expect(java_opts).to include( + "-javaagent:$PWD/.java-buildpack/opentelemetry_javaagent/opentelemetry_javaagent-#{version}.jar" + ) + end + + it 'sets the service name from the application name' do + component.release + + expect(java_opts).to include('-Dotel.service.name=GreatServiceTM') + end + + end + +end From 5699a500801a80533eb0b4d61e9cebd1335d38c3 Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Tue, 26 Sep 2023 13:35:05 -0400 Subject: [PATCH 756/812] Rename files to match naming convention. --- .../{opentelemetry_javaagent.yml => open_telemetry_javaagent.yml} | 0 ...lemetry_javaagent.md => framework-open_telemetry_javaagent.md} | 0 .../{opentelemetry_javaagent.rb => open_telemetry_javaagent.rb} | 0 ...telemtry_javaagent_spec.rb => open_telemtry_javaagent_spec.rb} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename config/{opentelemetry_javaagent.yml => open_telemetry_javaagent.yml} (100%) rename docs/{framework-opentelemetry_javaagent.md => framework-open_telemetry_javaagent.md} (100%) rename lib/java_buildpack/framework/{opentelemetry_javaagent.rb => open_telemetry_javaagent.rb} (100%) rename spec/java_buildpack/framework/{opentelemtry_javaagent_spec.rb => open_telemtry_javaagent_spec.rb} (100%) diff --git a/config/opentelemetry_javaagent.yml b/config/open_telemetry_javaagent.yml similarity index 100% rename from config/opentelemetry_javaagent.yml rename to config/open_telemetry_javaagent.yml diff --git a/docs/framework-opentelemetry_javaagent.md b/docs/framework-open_telemetry_javaagent.md similarity index 100% rename from docs/framework-opentelemetry_javaagent.md rename to docs/framework-open_telemetry_javaagent.md diff --git a/lib/java_buildpack/framework/opentelemetry_javaagent.rb b/lib/java_buildpack/framework/open_telemetry_javaagent.rb similarity index 100% rename from lib/java_buildpack/framework/opentelemetry_javaagent.rb rename to lib/java_buildpack/framework/open_telemetry_javaagent.rb diff --git a/spec/java_buildpack/framework/opentelemtry_javaagent_spec.rb b/spec/java_buildpack/framework/open_telemtry_javaagent_spec.rb similarity index 100% rename from spec/java_buildpack/framework/opentelemtry_javaagent_spec.rb rename to spec/java_buildpack/framework/open_telemtry_javaagent_spec.rb From 4e85dc0f999e80bebb8369f509af24808b49bf1a Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Wed, 27 Sep 2023 11:30:54 -0400 Subject: [PATCH 757/812] Update "user provided service" verbiage. --- docs/framework-open_telemetry_javaagent.md | 12 ++++++++++-- docs/framework-splunk_otel_java_agent.md | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/framework-open_telemetry_javaagent.md b/docs/framework-open_telemetry_javaagent.md index b10a9455b5..804d2e118f 100644 --- a/docs/framework-open_telemetry_javaagent.md +++ b/docs/framework-open_telemetry_javaagent.md @@ -20,8 +20,16 @@ Tags are printed to standard output by the buildpack detect script ## User-Provided Service -Users are currently expected to provide their own "custom user provided service" (cups) -instance and bind it to their application. The service MUST contain the string `otel-collector`. +Users are currently expected to `create-user-provided-service` (cups) of the collector +and bind it to their application. The service MUST contain the string `otel-collector`. + +For example, to create a service named `otel-collector` that represents an environment named `cf-demo`, you could use the following commands: + +``` +$ cf cups otel-collector -p '{"otel.resource.attributes": "deployment.environment=cf-demo"}' +$ cf bind-service myApp otel-collector +$ cf restage myApp +``` ### Choosing a version diff --git a/docs/framework-splunk_otel_java_agent.md b/docs/framework-splunk_otel_java_agent.md index 0ba30e97d5..e8b438376b 100644 --- a/docs/framework-splunk_otel_java_agent.md +++ b/docs/framework-splunk_otel_java_agent.md @@ -20,8 +20,8 @@ Tags are printed to standard output by the buildpack detect script ## User-Provided Service -Users are currently expected to provide their own "custom user provided service" (cups) -instance and bind it to their application. The service MUST contain the string `splunk-o11y`. +Users are currently expected to `create-user-provided-service` (cups) of the collector +and bind it to their application. The service MUST contain the string `splunk-o11y`. For example, to create a service named `splunk-o11y` that represents Observability Cloud realm `us0` and represents a user environment named `cf-demo`, you could use the following From f661d8ac0894df1631f480e52cb73fb89749ecd8 Mon Sep 17 00:00:00 2001 From: Ben Ross Date: Thu, 5 Oct 2023 13:58:54 -0700 Subject: [PATCH 758/812] Improved geode_store validation regex to identify gemfire or geode jars --- lib/java_buildpack/container/tomcat/tomcat_geode_store.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 6fda2f971d..5973f26fe3 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -137,7 +137,7 @@ def create_cache_client_xml def detect_geode_tomcat_version geode_tomcat_version = nil - geode_modules_tomcat_pattern = /geode-modules-tomcat(?[0-9]*).*.jar/.freeze + geode_modules_tomcat_pattern = /ge.*-modules-tomcat(?[0-9]*).*.jar/.freeze Dir.foreach(@droplet.sandbox + 'lib') do |file| if geode_modules_tomcat_pattern.match(file) unless geode_tomcat_version.nil? From d9bfa179767db3a589b28da05471aa43a5d0f66a Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Tue, 10 Oct 2023 16:28:10 -0400 Subject: [PATCH 759/812] Apply suggestions from code review Co-authored-by: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> --- ...javaagent_spec.rb => open_telemetry_javaagent_spec.rb} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename spec/java_buildpack/framework/{open_telemtry_javaagent_spec.rb => open_telemetry_javaagent_spec.rb} (84%) diff --git a/spec/java_buildpack/framework/open_telemtry_javaagent_spec.rb b/spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb similarity index 84% rename from spec/java_buildpack/framework/open_telemtry_javaagent_spec.rb rename to spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb index c1244ef4a7..940e5decff 100644 --- a/spec/java_buildpack/framework/open_telemtry_javaagent_spec.rb +++ b/spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb @@ -17,7 +17,7 @@ require 'spec_helper' require 'component_helper' -require 'java_buildpack/framework/opentelemetry_javaagent' +require 'java_buildpack/framework/open_telemetry_javaagent' require 'java_buildpack/util/tokenized_version' describe JavaBuildpack::Framework::OpenTelemetryJavaagent do @@ -37,21 +37,21 @@ end it 'detects with opentelemetry-javaagent' do - expect(component.detect).to eq("opentelemetry-javaagent=#{version}") + expect(component.detect).to eq("open-telemetry-javaagent=#{version}") end it 'downloads the opentelemetry javaagent jar', cache_fixture: 'stub-download.jar' do component.compile - expect(sandbox + "opentelemetry_javaagent-#{version}.jar").to exist + expect(sandbox + "open_telemetry_javaagent-#{version}.jar").to exist end it 'updates JAVA_OPTS' do component.release expect(java_opts).to include( - "-javaagent:$PWD/.java-buildpack/opentelemetry_javaagent/opentelemetry_javaagent-#{version}.jar" + "-javaagent:$PWD/.java-buildpack/open_telemetry_javaagent/open_telemetry_javaagent-#{version}.jar" ) end From ab6bb691f247bb869863994b8f147aabd367c75a Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Tue, 10 Oct 2023 16:37:41 -0400 Subject: [PATCH 760/812] Populate provided system properties from config. --- lib/java_buildpack/framework/open_telemetry_javaagent.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/java_buildpack/framework/open_telemetry_javaagent.rb b/lib/java_buildpack/framework/open_telemetry_javaagent.rb index bf28eb5941..b78049bbf2 100644 --- a/lib/java_buildpack/framework/open_telemetry_javaagent.rb +++ b/lib/java_buildpack/framework/open_telemetry_javaagent.rb @@ -34,6 +34,15 @@ def release java_opts = @droplet.java_opts java_opts.add_javaagent(@droplet.sandbox + jar_name) + credentials = @application.services.find_service(REQUIRED_SERVICE_NAME_FILTER)['credentials'] + # Add all otel.* credentials from the service bind as jvm system properties + credentials&.each do |key, value| + java_opts.add_system_property(key, value) if key.start_with?('otel.') + end + + # Set the otel.service.name to the application_name if not specified in credentials + return if credentials.key? 'otel.service.name' + # Set the otel.service.name to the application_name app_name = @application.details['application_name'] java_opts.add_system_property('otel.service.name', app_name) From 9e247374d1e08ac659eaf2557acd34a0ffe8a00d Mon Sep 17 00:00:00 2001 From: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> Date: Fri, 20 Oct 2023 12:48:06 +0100 Subject: [PATCH 761/812] Update packaging.yml Add updated release note/CVE links --- config/packaging.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index 8818f0c517..9e9c8d5889 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -92,18 +92,18 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u382b6/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u392b9/general/release-notes/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.20b8/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.21b10/general/release-notes/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujul2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.8b7/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.9b11/general/release-notes/)' jrebel_agent: name: JRebel Agent From c49a1122cf4954aa40dfb1b439b5e57f57359233 Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Mon, 30 Oct 2023 19:20:45 -0400 Subject: [PATCH 762/812] Fix #1035: Add Java 21 --- config/open_jdk_jre.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/open_jdk_jre.yml b/config/open_jdk_jre.yml index 27b70a03bd..8e706e2fb6 100644 --- a/config/open_jdk_jre.yml +++ b/config/open_jdk_jre.yml @@ -21,6 +21,7 @@ jre: - 1.8.0_+ - 11.+ - 17.+ + - 21.+ repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}" jvmkill_agent: version: 1.+ From 4be5af0ac50d0b25ebc84e4fb86f8aef237cd9ea Mon Sep 17 00:00:00 2001 From: Tyler Howard Date: Wed, 8 Nov 2023 12:23:54 -0500 Subject: [PATCH 763/812] Update Contrast Agent to 6.0 --- config/contrast_security_agent.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/contrast_security_agent.yml b/config/contrast_security_agent.yml index 9d45b2c2d9..60b5cae8da 100644 --- a/config/contrast_security_agent.yml +++ b/config/contrast_security_agent.yml @@ -15,5 +15,5 @@ # Configuration for the ContrastSecurity framework --- -version: 5.+ +version: 6.+ repository_root: https://download.run.pivotal.io/contrast-security From 3bf69ddcaac62328f8e5ddd1fff7122e7b6175dd Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Wed, 8 Nov 2023 17:35:23 -0500 Subject: [PATCH 764/812] Fix #1039: Make client certificate mapper support Spring Boot 3 * let it choose v2 of the jar when SB3 is detected * otherwise, continue as before with default v1 --- config/client_certificate_mapper.yml | 5 +++- docs/framework-client_certificate_mapper.md | 15 +++++++--- .../framework/client_certificate_mapper.rb | 21 +++++++++++++ .../client_certificate_mapper_spec.rb | 30 +++++++++++++++++++ 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/config/client_certificate_mapper.yml b/config/client_certificate_mapper.yml index a306eaba03..6be2855709 100644 --- a/config/client_certificate_mapper.yml +++ b/config/client_certificate_mapper.yml @@ -16,4 +16,7 @@ # Container security provider configuration --- version: 1.+ -repository_root: "{default.repository.root}/client-certificate-mapper" +version_lines: + - 2.+ +repository_root: "https://anthonydahanne.github.io/java-buildpack-client-certificate-mapper" +javax_forced: false \ No newline at end of file diff --git a/docs/framework-client_certificate_mapper.md b/docs/framework-client_certificate_mapper.md index 1927985803..4e2c52c8ec 100644 --- a/docs/framework-client_certificate_mapper.md +++ b/docs/framework-client_certificate_mapper.md @@ -1,6 +1,11 @@ # Client Certificate Mapper -The Client Certificate Mapper Framework adds a Servlet Filter to applications that will that maps the `X-Forwarded-Client-Cert` to the `javax.servlet.request.X509Certificate` Servlet attribute. +The Client Certificate Mapper Framework adds a Servlet Filter to applications that will that maps the `X-Forwarded-Client-Cert` to the `javax|jakarta.servlet.request.X509Certificate` Servlet attribute. +The Client Certificate Mapper Framework will download a helper library, [java-buildpack-client-certificate-mapper][library repository], that will enrich Spring Boot applications classpath. + +If the app you're deploying is using Spring Boot 2 or earlier, the latest 1.x version (`javax` support) from [the listing][this listing] will be downloaded. + +If the app you're deploying is using Spring Boot 3, the latest 2.x version (`jakarta` support) from [the listing][this listing] will be downloaded. @@ -18,10 +23,11 @@ For general information on configuring the buildpack, including how to specify c The framework can be configured by modifying the [`config/client_certificate_mapper.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there. -| Name | Description -| ---- | ----------- +| Name | Description +|-------------------| ----------- | `repository_root` | The URL of the Container Customizer repository index ([details][repositories]). -| `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. +| `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. +| `javax_forced` | You can force the download of the v1.x version of the [library][library repository] which is based on `javax` naming. ## Servlet Filter The [Servlet Filter][] added by this framework maps the `X-Forwarded-Client-Cert` to the `javax.servlet.request.X509Certificate` Servlet attribute for each request. The `X-Forwarded-Client-Cert` header is contributed by the Cloud Foundry Router and contains the any TLS certificate presented by a client for mututal TLS authentication. This certificate can then be used by any standard Java security framework to establish authentication and authorization for a request. @@ -32,3 +38,4 @@ The [Servlet Filter][] added by this framework maps the `X-Forwarded-Client-Cert [Servlet Filter]: https://github.com/cloudfoundry/java-buildpack-client-certificate-mapper [this listing]: http://download.pivotal.io.s3.amazonaws.com/container-security-provider/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering +[library repository]: https://github.com:cloudfoundry/java-buildpack-client-certificate-mapper.git diff --git a/lib/java_buildpack/framework/client_certificate_mapper.rb b/lib/java_buildpack/framework/client_certificate_mapper.rb index 599d3a6ba2..d92da14a22 100644 --- a/lib/java_buildpack/framework/client_certificate_mapper.rb +++ b/lib/java_buildpack/framework/client_certificate_mapper.rb @@ -17,15 +17,28 @@ require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' +require 'java_buildpack/util/spring_boot_utils' module JavaBuildpack module Framework # Encapsulates the functionality for contributing an mTLS client certificate mapper to the application. class ClientCertificateMapper < JavaBuildpack::Component::VersionedDependencyComponent + include JavaBuildpack::Util + + def initialize(context) + @spring_boot_utils = JavaBuildpack::Util::SpringBootUtils.new + @configuration = context[:configuration] + super(context) + end # (see JavaBuildpack::Component::BaseComponent#compile) def compile + if spring_boot_3? && !@configuration['javax_forced'] + spring_boot_3_configuration = @configuration + spring_boot_3_configuration['version'] = '2.+' + @version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, spring_boot_3_configuration) + end download_jar @droplet.additional_libraries << (@droplet.sandbox + jar_name) end @@ -42,6 +55,14 @@ def supports? true end + private + + def spring_boot_3? + # print '@application.details: ' + @application.details.to_s + @spring_boot_utils.is?(@application) && Gem::Version.new((@spring_boot_utils.version @application)).release >= + Gem::Version.new('3.0.0') + end + end end diff --git a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb index 37120b3709..3f52001de7 100644 --- a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb +++ b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb @@ -33,6 +33,36 @@ expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") + # version was not patched by the compile step + expect(configuration).to eq({}) + end + + + it 'configures client certificate mapper to download version 2.+ during compile of spring boot 3 app', + app_fixture: 'framework_java_cf_boot_3', + cache_fixture: 'stub-client-certificate-mapper.jar' do + + component.compile + + expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist + expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") + # version of the dep. was forced to 2.+ by the compile step, because Spring Boot 3 was found + expect(configuration).to eq({ 'version' => '2.+' }) + end + + context 'user forced javax to be used' do + let(:configuration) { { 'javax_forced' => true } } + it 'configures client certificate mapper to download version 1 during compile of spring boot 3 app ', + app_fixture: 'framework_java_cf_boot_3', + cache_fixture: 'stub-client-certificate-mapper.jar' do + + component.compile + + expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist + expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") + # user prevented version 2.+, forcing javax + expect(configuration).to eq({ 'javax_forced' => true }) + end end it 'adds the jar to the additional libraries during release', From f9b4a20df6c24c1a979f317bce927ad672e3d149 Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Thu, 14 Dec 2023 11:05:51 -0500 Subject: [PATCH 765/812] Fix cloudfoundry#1039 Make client certificate mapper support Jakarta EE; using a single library that can support SB2, SB3, JEE and JakartaEE apps --- config/client_certificate_mapper.yml | 5 ++-- docs/framework-client_certificate_mapper.md | 6 +--- .../framework/client_certificate_mapper.rb | 21 ------------- .../client_certificate_mapper_spec.rb | 30 ------------------- 4 files changed, 3 insertions(+), 59 deletions(-) diff --git a/config/client_certificate_mapper.yml b/config/client_certificate_mapper.yml index 6be2855709..e32fbedc82 100644 --- a/config/client_certificate_mapper.yml +++ b/config/client_certificate_mapper.yml @@ -15,8 +15,7 @@ # Container security provider configuration --- -version: 1.+ +version: 2.+ version_lines: - 2.+ -repository_root: "https://anthonydahanne.github.io/java-buildpack-client-certificate-mapper" -javax_forced: false \ No newline at end of file +repository_root: "{default.repository.root}/client-certificate-mapper" \ No newline at end of file diff --git a/docs/framework-client_certificate_mapper.md b/docs/framework-client_certificate_mapper.md index 4e2c52c8ec..5d3852b5a6 100644 --- a/docs/framework-client_certificate_mapper.md +++ b/docs/framework-client_certificate_mapper.md @@ -1,11 +1,8 @@ # Client Certificate Mapper The Client Certificate Mapper Framework adds a Servlet Filter to applications that will that maps the `X-Forwarded-Client-Cert` to the `javax|jakarta.servlet.request.X509Certificate` Servlet attribute. -The Client Certificate Mapper Framework will download a helper library, [java-buildpack-client-certificate-mapper][library repository], that will enrich Spring Boot applications classpath. +The Client Certificate Mapper Framework will download a helper library, [java-buildpack-client-certificate-mapper][library repository], that will enrich Spring Boot (2 and 3), as well as JEE / JakartaEE applications classpath with a servlet filter. -If the app you're deploying is using Spring Boot 2 or earlier, the latest 1.x version (`javax` support) from [the listing][this listing] will be downloaded. - -If the app you're deploying is using Spring Boot 3, the latest 2.x version (`jakarta` support) from [the listing][this listing] will be downloaded.
Detection Criterion
@@ -27,7 +24,6 @@ The framework can be configured by modifying the [`config/client_certificate_map |-------------------| ----------- | `repository_root` | The URL of the Container Customizer repository index ([details][repositories]). | `version` | The version of Container Customizer to use. Candidate versions can be found in [this listing][]. -| `javax_forced` | You can force the download of the v1.x version of the [library][library repository] which is based on `javax` naming. ## Servlet Filter The [Servlet Filter][] added by this framework maps the `X-Forwarded-Client-Cert` to the `javax.servlet.request.X509Certificate` Servlet attribute for each request. The `X-Forwarded-Client-Cert` header is contributed by the Cloud Foundry Router and contains the any TLS certificate presented by a client for mututal TLS authentication. This certificate can then be used by any standard Java security framework to establish authentication and authorization for a request. diff --git a/lib/java_buildpack/framework/client_certificate_mapper.rb b/lib/java_buildpack/framework/client_certificate_mapper.rb index d92da14a22..599d3a6ba2 100644 --- a/lib/java_buildpack/framework/client_certificate_mapper.rb +++ b/lib/java_buildpack/framework/client_certificate_mapper.rb @@ -17,28 +17,15 @@ require 'java_buildpack/component/versioned_dependency_component' require 'java_buildpack/framework' -require 'java_buildpack/util/spring_boot_utils' module JavaBuildpack module Framework # Encapsulates the functionality for contributing an mTLS client certificate mapper to the application. class ClientCertificateMapper < JavaBuildpack::Component::VersionedDependencyComponent - include JavaBuildpack::Util - - def initialize(context) - @spring_boot_utils = JavaBuildpack::Util::SpringBootUtils.new - @configuration = context[:configuration] - super(context) - end # (see JavaBuildpack::Component::BaseComponent#compile) def compile - if spring_boot_3? && !@configuration['javax_forced'] - spring_boot_3_configuration = @configuration - spring_boot_3_configuration['version'] = '2.+' - @version, @uri = JavaBuildpack::Repository::ConfiguredItem.find_item(@component_name, spring_boot_3_configuration) - end download_jar @droplet.additional_libraries << (@droplet.sandbox + jar_name) end @@ -55,14 +42,6 @@ def supports? true end - private - - def spring_boot_3? - # print '@application.details: ' + @application.details.to_s - @spring_boot_utils.is?(@application) && Gem::Version.new((@spring_boot_utils.version @application)).release >= - Gem::Version.new('3.0.0') - end - end end diff --git a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb index 3f52001de7..37120b3709 100644 --- a/spec/java_buildpack/framework/client_certificate_mapper_spec.rb +++ b/spec/java_buildpack/framework/client_certificate_mapper_spec.rb @@ -33,36 +33,6 @@ expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") - # version was not patched by the compile step - expect(configuration).to eq({}) - end - - - it 'configures client certificate mapper to download version 2.+ during compile of spring boot 3 app', - app_fixture: 'framework_java_cf_boot_3', - cache_fixture: 'stub-client-certificate-mapper.jar' do - - component.compile - - expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist - expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") - # version of the dep. was forced to 2.+ by the compile step, because Spring Boot 3 was found - expect(configuration).to eq({ 'version' => '2.+' }) - end - - context 'user forced javax to be used' do - let(:configuration) { { 'javax_forced' => true } } - it 'configures client certificate mapper to download version 1 during compile of spring boot 3 app ', - app_fixture: 'framework_java_cf_boot_3', - cache_fixture: 'stub-client-certificate-mapper.jar' do - - component.compile - - expect(sandbox + "client_certificate_mapper-#{version}.jar").to exist - expect(additional_libraries).to include(sandbox + "client_certificate_mapper-#{version}.jar") - # user prevented version 2.+, forcing javax - expect(configuration).to eq({ 'javax_forced' => true }) - end end it 'adds the jar to the additional libraries during release', From 18729c23f007c630efdb845020147f5730b65d57 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 14 Dec 2023 22:10:09 +0000 Subject: [PATCH 766/812] adds packaging links for Java 21 --- config/packaging.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/packaging.yml b/config/packaging.yml index 9e9c8d5889..463850e7b0 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -105,6 +105,11 @@ jre-17: cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.9b11/general/release-notes/)' +jre-21: + name: OpenJDK JRE 21 + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.1b12/general/release-notes/)' + jrebel_agent: name: JRebel Agent release_notes: '[ChangeLog](https://www.jrebel.com/products/jrebel/changelog)' From 2348edf831ea8606638c7382a2c4729fb6f18767 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Tue, 19 Dec 2023 15:26:45 +0000 Subject: [PATCH 767/812] updates doc and adds packaging entry for new otel framework --- config/packaging.yml | 4 ++++ docs/framework-open_telemetry_javaagent.md | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/config/packaging.yml b/config/packaging.yml index 463850e7b0..2f30ac7415 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -151,6 +151,10 @@ new_relic_agent: name: New Relic Agent release_notes: '[Release Notes](https://docs.newrelic.com/docs/release-notes/agent-release-notes/java-release-notes/)' +open_telemetry_javaagent: + name: Open Telemetry Agent + release_notes: '[Release Notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases)' + postgresql_jdbc: name: PostgreSQL JDBC Driver release_notes: '[ChangeLog](https://jdbc.postgresql.org/documentation/changelog.html)' diff --git a/docs/framework-open_telemetry_javaagent.md b/docs/framework-open_telemetry_javaagent.md index 804d2e118f..26706700cd 100644 --- a/docs/framework-open_telemetry_javaagent.md +++ b/docs/framework-open_telemetry_javaagent.md @@ -26,11 +26,13 @@ and bind it to their application. The service MUST contain the string `otel-coll For example, to create a service named `otel-collector` that represents an environment named `cf-demo`, you could use the following commands: ``` -$ cf cups otel-collector -p '{"otel.resource.attributes": "deployment.environment=cf-demo"}' +$ cf cups otel-collector -p '{"otel.exporter.otlp.endpoint" : "https://my-collector-endpoint", "otel.exporter.otlp.headers" : "authorization=Basic SOMEBAS64STRING","otel.exporter.otlp.protocol" : "grpc", "otel.traces.exporter" : "otlp", "otel.metrics.exporter" : "otlp", "otel.resource.attributes": "deployment.environment=cf-demo"}' $ cf bind-service myApp otel-collector $ cf restage myApp ``` +Additional configuration options for the Agent can be found [here](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/#configuring-with-environment-variables) + ### Choosing a version Most users should skip this and simply use the latest version of the agent available (the default). From 7e225de7d87764d61d86bbaef9bb421c6db0b137 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Tue, 19 Dec 2023 17:28:03 +0000 Subject: [PATCH 768/812] fixes test for otel agent --- .../framework/open_telemetry_javaagent_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb b/spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb index 940e5decff..9f8f260550 100644 --- a/spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb +++ b/spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb @@ -48,14 +48,22 @@ end it 'updates JAVA_OPTS' do + allow(services).to receive(:find_service).and_return('credentials' => { 'otel.exporter.otlp.endpoint' => 'https://my-collector-endpoint', + 'ignored' => 'not used', + 'otel.foo' => 'bar' }) component.release expect(java_opts).to include( "-javaagent:$PWD/.java-buildpack/open_telemetry_javaagent/open_telemetry_javaagent-#{version}.jar" ) + expect(java_opts).to include('-Dotel.exporter.otlp.endpoint=https://my-collector-endpoint') + expect(java_opts).to include('-Dotel.foo=bar') end it 'sets the service name from the application name' do + allow(services).to receive(:find_service).and_return('credentials' => { 'otel.exporter.otlp.endpoint' => 'https://my-collector-endpoint', + 'ignored' => 'not used', + 'otel.foo' => 'bar' }) component.release expect(java_opts).to include('-Dotel.service.name=GreatServiceTM') From 93226a348fcbc2ae7589ab205f74b86f7e6c24d1 Mon Sep 17 00:00:00 2001 From: Johannes Mittendorfer Date: Wed, 25 Oct 2023 13:36:50 +0200 Subject: [PATCH 769/812] Migrate dynatrace integration to LD_PRELOAD Migrate the dnytrace integration to use the LD_PRELOAD method as used within other buildpacks. * Set LD_PRELOAD environment variable instead of java options * adapt tests and test fixtures --- .../framework/dynatrace_one_agent.rb | 10 ++++++---- .../dynatrace_one_agent/manifest.json | 6 +++--- spec/fixtures/stub-dynatrace-one-agent.zip | Bin 1276 -> 1408 bytes .../framework/dynatrace_one_agent_spec.rb | 11 +++++------ 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 0b919012f9..7e49899529 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -68,8 +68,8 @@ def release manifest = agent_manifest - @droplet.java_opts.add_agentpath(agent_path(manifest)) - @droplet.java_opts.add_preformatted_options('-Xshare:off') + environment_variables = @droplet.environment_variables + environment_variables.add_environment_variable(LD_PRELOAD, agent_path(manifest)) dynatrace_environment_variables(manifest) end @@ -99,6 +99,8 @@ def supports? DT_NETWORK_ZONE = 'DT_NETWORK_ZONE' + LD_PRELOAD = 'LD_PRELOAD' + ENVIRONMENTID = 'environmentid' FILTER = /dynatrace/.freeze @@ -126,8 +128,8 @@ def agent_manifest def agent_path(manifest) technologies = manifest['technologies'] - java_binaries = technologies['java']['linux-x86-64'] - loader = java_binaries.find { |bin| bin['binarytype'] == 'loader' } + java_binaries = technologies['process']['linux-x86-64'] + loader = java_binaries.find { |bin| bin['binarytype'] == 'primary' } @droplet.sandbox + loader['path'] end diff --git a/spec/fixtures/framework_dynatrace_one_agent/.java-buildpack/dynatrace_one_agent/manifest.json b/spec/fixtures/framework_dynatrace_one_agent/.java-buildpack/dynatrace_one_agent/manifest.json index a2c5ae6e8c..6af71ec43a 100644 --- a/spec/fixtures/framework_dynatrace_one_agent/.java-buildpack/dynatrace_one_agent/manifest.json +++ b/spec/fixtures/framework_dynatrace_one_agent/.java-buildpack/dynatrace_one_agent/manifest.json @@ -1,10 +1,10 @@ { "technologies" : { - "java" : { + "process" : { "linux-x86-64" : [ { - "path": "agent/lib64/liboneagentloader.so", - "binarytype" : "loader" + "path": "agent/lib64/liboneagentproc.so", + "binarytype" : "primary" } ] } diff --git a/spec/fixtures/stub-dynatrace-one-agent.zip b/spec/fixtures/stub-dynatrace-one-agent.zip index 052c460260abc86862d2cb0effa22b3a281f4f6b..b05d3927987092f764aae883ad0c8b1d929c0ed0 100644 GIT binary patch literal 1408 zcmWIWW@Zs#0D(^-HXdLGlwe~}U`R|)%`4Fl4dG>Azxi-wn4GX>stgd9R&X;gvb|k}c3Ven1SOv3iYzfrEh$%}H`-CIQXM&r1adSV2*KvR-jMIM{4}uDqG~IUI}G z%nSkE>>ME1F+rUO2}qD_Ng*ztFn3=9GI)Wu=Yb910W|mp5Mzmx z)z5+g0<^q!wa%S69~`tHD8T57v5CP|V-v&c#zqDv#v4q`E|{8_ni-mgUt-kM^*rl+ zMw^rOYYF4(wt|UEojz?2{ygDHiT44f1ksZ}ckWzTIrC(vs>AJ=&p}+Dj6ZvIId&}; zonqwW#nrX;%h%wAkJ^4|oSIr<=%7Tgpe6+XFY3$b5h>7+X$27%Oq_G!h7fHDU*=Sg*#O{qOpfF`= UG{Bpc4dhgIAe;m=?FQH)01~(~O#lD@ literal 1276 zcmWIWW@h1H0D;dTHXdLGlwf0!VMt6*%`4Fl4dG;9zWH!v*o(~1;iVPa42&!{CmO1< z>`}O=8h}$j7hHc*W*(7du-4hTA-jPaZbou`UK+#@t=DHl@H%8kkc%g>Av|zHax#<5 zOdzI|quQ}lb3Qm|Lr{Rx z6=M^FtHvgV*Nu$~OpG^}m|ZY6F*P$Z4Zp;wsq1;x`;0ax@7EH>)ole6mpXmg9Q=90 zlM?R(ObMbVf9~A5v~uRjPF087F`t9DJ{f=Z>T>K_EIP%=%ZsaP?U%2?3m>)p(l|A> z#9*q#Le0RAr>mYaF(6`Gd=6@C$pJkQnO_>5kzbmV;+J3Ikyw@*npc%sP>`D9o2pk* zQ3CeaIr+2L1Bj7Hju}^4lz_&l0K;2H5EGU%Ss^JCBUR!yi;Dr-EC;w*kW@<8Jj^tT zY+ei8JZOpq8VE|UcpQkCUXcwv2{#aydVwZ_QZF78G1D&0Ljr@$T;DeZmJtYHe z0i|TDw%|&~5LJ>I@0ckH+2KY^3 Date: Tue, 31 Oct 2023 13:13:19 +0100 Subject: [PATCH 770/812] Enable FIPS mode when requested This adds an option to enable FIPS mode if enablefips is set. OneAgent uses the FIPS mode to be compliant with the FIPS 140-3 computer security standard. --- docs/framework-dynatrace_one_agent.md | 1 + .../framework/dynatrace_one_agent.rb | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/framework-dynatrace_one_agent.md b/docs/framework-dynatrace_one_agent.md index cf0d3cfa89..6a88ef5ac7 100644 --- a/docs/framework-dynatrace_one_agent.md +++ b/docs/framework-dynatrace_one_agent.md @@ -30,6 +30,7 @@ The credential payload of the service may contain the following entries: | `environmentid` | Your Dynatrace environment ID is the unique identifier of your Dynatrace environment. You can find it in the deploy Dynatrace section within your environment. | `networkzone` | (Optional) Network zones are Dynatrace entities that represent your network structure. They help you to route the traffic efficiently, avoiding unnecessary traffic across data centers and network regions. Enter the network zone you wish to pass to the server during the OneAgent Download. | `skiperrors` | (Optional) The errors during agent download are skipped and the injection is disabled. Use this option at your own risk. Possible values are 'true' and 'false'. This option is disabled by default! +| `enablefips`| (Optional) Enables the use of [FIPS 140 cryptographic algorithms](https://docs.dynatrace.com/docs/shortlink/oneagentctl#fips-140). Possible values are 'true' and 'false'. This option is disabled by default! ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 7e49899529..3914f7dd2c 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -71,6 +71,10 @@ def release environment_variables = @droplet.environment_variables environment_variables.add_environment_variable(LD_PRELOAD, agent_path(manifest)) + if enable_fips? + File.delete(@droplet.sandbox + 'agent/dt_fips_disabled.flag') + end + dynatrace_environment_variables(manifest) end @@ -87,6 +91,8 @@ def supports? APITOKEN = 'apitoken' + ENABLE_FIPS = 'enablefips' + DT_APPLICATION_ID = 'DT_APPLICATIONID' DT_CONNECTION_POINT = 'DT_CONNECTION_POINT' @@ -109,8 +115,9 @@ def supports? SKIP_ERRORS = 'skiperrors' - private_constant :APIURL, :APITOKEN, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_NETWORK_ZONE, :DT_LOGSTREAM, - :DT_TENANT, :DT_TENANTTOKEN, :ENVIRONMENTID, :FILTER, :NETWORKZONE, :SKIP_ERRORS + private_constant :APIURL, :APITOKEN, :ENABLE_FIPS, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_NETWORK_ZONE, + :DT_LOGSTREAM, :DT_TENANT, :DT_TENANTTOKEN, :LD_PRELOAD, :ENVIRONMENTID, :FILTER, :NETWORKZONE, + :SKIP_ERRORS def agent_download_url download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ @@ -193,7 +200,11 @@ def logstream? end def skip_errors? - credentials[SKIP_ERRORS].to_b + credentials[SKIP_ERRORS] == "true" + end + + def enable_fips? + credentials[ENABLE_FIPS] == "true" end def tenanttoken(manifest) From a42f608d69b7c5c7f8179a8bd6369624f996b15c Mon Sep 17 00:00:00 2001 From: Johannes Mittendorfer Date: Wed, 20 Dec 2023 14:32:01 +0100 Subject: [PATCH 771/812] Linter fixes Co-authored-by: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 3914f7dd2c..039b10da86 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -71,9 +71,7 @@ def release environment_variables = @droplet.environment_variables environment_variables.add_environment_variable(LD_PRELOAD, agent_path(manifest)) - if enable_fips? - File.delete(@droplet.sandbox + 'agent/dt_fips_disabled.flag') - end + File.delete(@droplet.sandbox + 'agent/dt_fips_disabled.flag') if enable_fips? dynatrace_environment_variables(manifest) end From 48d0e026934326d205be5d3cf039bed202383881 Mon Sep 17 00:00:00 2001 From: Johannes Mittendorfer Date: Wed, 20 Dec 2023 14:32:13 +0100 Subject: [PATCH 772/812] Linter fixes Co-authored-by: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 039b10da86..126ccc9524 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -198,7 +198,7 @@ def logstream? end def skip_errors? - credentials[SKIP_ERRORS] == "true" + credentials[SKIP_ERRORS] == 'true' end def enable_fips? From 0490c5d82edd2faa33a8a5eb10cc1c73e0662091 Mon Sep 17 00:00:00 2001 From: Johannes Mittendorfer Date: Wed, 20 Dec 2023 14:32:27 +0100 Subject: [PATCH 773/812] Linter fixes Co-authored-by: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 126ccc9524..23206f26d2 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -202,7 +202,7 @@ def skip_errors? end def enable_fips? - credentials[ENABLE_FIPS] == "true" + credentials[ENABLE_FIPS] == 'true' end def tenanttoken(manifest) From 4b1f6ca709b23a3905fe5b916644c7329a630a42 Mon Sep 17 00:00:00 2001 From: Johannes Mittendorfer Date: Wed, 20 Dec 2023 14:32:36 +0100 Subject: [PATCH 774/812] Linter fixes Co-authored-by: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> --- spec/java_buildpack/framework/dynatrace_one_agent_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb index d11e2e2944..53c686a1ce 100644 --- a/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb +++ b/spec/java_buildpack/framework/dynatrace_one_agent_spec.rb @@ -60,7 +60,7 @@ component.release expect(environment_variables).to include('LD_PRELOAD=$PWD/.java-buildpack/dynatrace_one_agent/agent/lib64/' \ - 'liboneagentproc.so') + 'liboneagentproc.so') end it 'updates environment variables', From b7a7356797af2473c667ed2c1b86bf03ac221b10 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Tue, 23 Jan 2024 16:25:21 +0000 Subject: [PATCH 775/812] updates release notes for Java quarterly patches --- config/packaging.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index 2f30ac7415..001dc0be88 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -92,23 +92,23 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u392b9/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u402b7/general/release-notes/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.21b10/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.22b12/general/release-notes/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.9b11/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.10b13/general/release-notes/)' jre-21: name: OpenJDK JRE 21 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2023.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.1b12/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.2b14/general/release-notes/)' jrebel_agent: name: JRebel Agent From 367bc819398839d387ee907ab615e19f9fe48b4b Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 29 Feb 2024 11:38:28 +0000 Subject: [PATCH 776/812] improvement to condition to trigger java-cfenv framework --- docs/framework-java-cfenv.md | 2 +- lib/java_buildpack/framework/java_cf_env.rb | 4 ++-- lib/java_buildpack/util/spring_boot_utils.rb | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/framework-java-cfenv.md b/docs/framework-java-cfenv.md index 1e1fe474a7..e9bbb31c71 100644 --- a/docs/framework-java-cfenv.md +++ b/docs/framework-java-cfenv.md @@ -8,7 +8,7 @@ It also sets the 'cloud' profile for Spring Boot applications, as the Spring Aut
Detection Criterion
- + diff --git a/lib/java_buildpack/framework/java_cf_env.rb b/lib/java_buildpack/framework/java_cf_env.rb index 3b3644a040..51a7a211a5 100644 --- a/lib/java_buildpack/framework/java_cf_env.rb +++ b/lib/java_buildpack/framework/java_cf_env.rb @@ -53,8 +53,8 @@ def supports? private def spring_boot_3? - @spring_boot_utils.is?(@application) && Gem::Version.new((@spring_boot_utils.version @application)).release >= - Gem::Version.new('3.0.0') + @spring_boot_utils.is?(@application) && + Gem::Version.new((@spring_boot_utils.version_strict @application)).release >= Gem::Version.new('3.0.0') end def java_cfenv? diff --git a/lib/java_buildpack/util/spring_boot_utils.rb b/lib/java_buildpack/util/spring_boot_utils.rb index bdcfe329c2..28bde3c063 100644 --- a/lib/java_buildpack/util/spring_boot_utils.rb +++ b/lib/java_buildpack/util/spring_boot_utils.rb @@ -87,6 +87,14 @@ def version(application) @jar_finder.version(application) end + # The version of Spring Boot used by the application - only considers the MANIFEST entry + # + # @param [Application] application the application to search + # @return [String] the version of Spring Boot used by the application + def version_strict(application) + JavaBuildpack::Util::JavaMainUtils.manifest(application)[SPRING_BOOT_VERSION] + end + private SPRING_BOOT_LIB = 'Spring-Boot-Lib' From 1b541fcfdb131455243f7171c8a9259eb80165f3 Mon Sep 17 00:00:00 2001 From: Anthony Dahanne Date: Fri, 1 Mar 2024 11:38:56 -0500 Subject: [PATCH 777/812] Test for improvement to condition to trigger java-cfenv framework --- .../framework_java_not_spring_boot3/META-INF/MANIFEST.MF | 2 ++ .../WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar | 0 spec/java_buildpack/framework/java_cfenv_spec.rb | 6 ++++++ 3 files changed, 8 insertions(+) create mode 100644 spec/fixtures/framework_java_not_spring_boot3/META-INF/MANIFEST.MF create mode 100644 spec/fixtures/framework_java_not_spring_boot3/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar diff --git a/spec/fixtures/framework_java_not_spring_boot3/META-INF/MANIFEST.MF b/spec/fixtures/framework_java_not_spring_boot3/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..a2cf1b406d --- /dev/null +++ b/spec/fixtures/framework_java_not_spring_boot3/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Main-Class: org.springframework.boot.loader.JarLauncher + diff --git a/spec/fixtures/framework_java_not_spring_boot3/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar b/spec/fixtures/framework_java_not_spring_boot3/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/java_cfenv_spec.rb b/spec/java_buildpack/framework/java_cfenv_spec.rb index bfd67e7729..e461823fd2 100644 --- a/spec/java_buildpack/framework/java_cfenv_spec.rb +++ b/spec/java_buildpack/framework/java_cfenv_spec.rb @@ -39,6 +39,12 @@ expect(component.detect).to be_nil end + it 'does not detect with Spring Boot 3 named jar but not Spring Boot 3 Manifest', + app_fixture: 'framework_java_not_spring_boot3' do + + expect(component.detect).to be_nil + end + it 'does not detect with Spring Boot 3 & java-cfenv present', app_fixture: 'framework_java_cf_exists' do From 8e12a834553d0fc3097b9e79be327815429bc213 Mon Sep 17 00:00:00 2001 From: Sophie Wigmore Date: Mon, 4 Mar 2024 12:16:24 -0500 Subject: [PATCH 778/812] Add release reminder workflow --- .github/workflows/release-reminder.yml | 98 ++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 .github/workflows/release-reminder.yml diff --git a/.github/workflows/release-reminder.yml b/.github/workflows/release-reminder.yml new file mode 100644 index 0000000000..a5998d4010 --- /dev/null +++ b/.github/workflows/release-reminder.yml @@ -0,0 +1,98 @@ +name: Release Reminder + +on: + schedule: + - cron: '0 0 * * 4' # Run at midnight on Thursdays + workflow_dispatch: {} + +jobs: + determine-date: + name: Release buildpacks on 2nd and 4th Thursday of the month + runs-on: ubuntu-22.04 + outputs: + should_run: ${{ steps.should_run.outputs.bool }} + steps: + - name: Should run + id: should_run + run: | + if [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then + echo "Skipping date check, because workflow was run manually" + echo "bool=true" >> "${GITHUB_OUTPUT}" + else + day_of_month=$(date +%d) + # Check if it's the second or fourth Thursday of the month + # second thursday of the month will always be between day 8 and 14 (inclusive) + if [[ "$day_of_month" -ge "8" && "$day_of_month" -le "14" ]]; then + echo "It's the second Thursday of the month" + echo "bool=true" >> "${GITHUB_OUTPUT}" + # fourth thursday of the month will always be between day 21 and 28 (inclusive) + elif [[ "$day_of_month" -ge "22" && "$day_of_month" -le "28" ]]; then + echo "It's the fourth Thursday of the month" + echo "bool=true" >> "${GITHUB_OUTPUT}" + else + echo "It's another Thursday of the month" + echo "bool=false" >> "${GITHUB_OUTPUT}" + fi + fi + reminder: + name: Reminder + runs-on: ubuntu-22.04 + needs: [ determine-date ] + if: ${{ needs.determine-date.outputs.should_run == 'true' }} + steps: + - name: Get Date + id: date + run: | + today=$(date +'%m-%d') + window_close_date=$(date -d "+5 days" +'%m-%d') + + echo "today=$today" >> "${GITHUB_OUTPUT}" + echo "window_close_date=$window_close_date" >> "${GITHUB_OUTPUT}" + + - name: Checkout + uses: actions/checkout@v3 + with: + token: ${{ secrets.CF_BOT_GITHUB_TOKEN }} + ref: develop + fetch-depth: 0 + + - name: Get Latest Version + id: latest-version + run: | + echo "val=$(git describe --abbrev=0 --tag)" >> "${GITHUB_OUTPUT}" + + - name: PHP specific task + id: php-specific + if: github.repository == 'cloudfoundry/php-buildpack' + run: | + echo 'task=* Bump PHP modules. See [doc](https://github.com/cloudfoundry/buildpacks-ci/tree/master/scripts/php-modules#pre-buildpack-release-task)' >> "${GITHUB_OUTPUT}" + echo 'title=Bump PHP Modules and ' >> "${GITHUB_OUTPUT}" + + - name: File Issue + id: file-issue + uses: paketo-buildpacks/github-config/actions/issue/file@main + with: + token: ${{ secrets.CF_BOT_GITHUB_TOKEN }} + repo: ${{ github.repository }} + issue_title: "${{ steps.php-specific.outputs.title }}Release: ${{ github.event.repository.name }} (${{ steps.date.outputs.today }})" + issue_body: | + Release reminder for ${{ github.event.repository.name }} + + The ideal release date window for this buildpack starts on: ${{ steps.date.outputs.today }} and ends on ${{ steps.date.outputs.window_close_date }}. + + ${{ steps.php-specific.outputs.task }} + * See [diff from latest version]("https://github.com/${{ github.repository }}/compare/${{ steps.latest-version.outputs.val }}..develop") and validate if a release is required. + * Make sure the latest commit on `develop` has passed tests on the [CI](https://buildpacks.ci.cf-app.com/teams/main/pipelines/${{ github.event.repository.name }}) + * Refer [release instructions](https://github.com/pivotal-cf/tanzu-buildpacks/wiki/Releasing-CF-Buildpacks). (private link) + + - name: Add issue to project + id: issue-to-proj + uses: paketo-buildpacks/github-config/actions/issue/add-to-project@main + with: + # CF buildpacks project - https://github.com/orgs/cloudfoundry/projects/37 + project-org: cloudfoundry + project-num: 37 + field-name: Workstream + option-name: Release Train + issue-node-id: ${{ steps.file-issue.outputs.node-id }} + token: ${{ secrets.CF_BOT_GITHUB_TOKEN }} From dee8fa6c370ba55765ae16e5202430fac44da8ed Mon Sep 17 00:00:00 2001 From: Sophie Wigmore Date: Mon, 4 Mar 2024 15:23:45 -0500 Subject: [PATCH 779/812] Update release-reminder workflow --- .github/workflows/release-reminder.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-reminder.yml b/.github/workflows/release-reminder.yml index a5998d4010..304d4468cb 100644 --- a/.github/workflows/release-reminder.yml +++ b/.github/workflows/release-reminder.yml @@ -7,7 +7,7 @@ on: jobs: determine-date: - name: Release buildpacks on 2nd and 4th Thursday of the month + name: Release buildpacks on 2nd and last Thursdays of the month runs-on: ubuntu-22.04 outputs: should_run: ${{ steps.should_run.outputs.bool }} @@ -20,14 +20,16 @@ jobs: echo "bool=true" >> "${GITHUB_OUTPUT}" else day_of_month=$(date +%d) - # Check if it's the second or fourth Thursday of the month + last_day_cutoff=$(expr $(date -d "-$(date +%d) days month" +%d) - 6) + # Check if it's the second or last Thursday of the month # second thursday of the month will always be between day 8 and 14 (inclusive) if [[ "$day_of_month" -ge "8" && "$day_of_month" -le "14" ]]; then echo "It's the second Thursday of the month" echo "bool=true" >> "${GITHUB_OUTPUT}" - # fourth thursday of the month will always be between day 21 and 28 (inclusive) - elif [[ "$day_of_month" -ge "22" && "$day_of_month" -le "28" ]]; then - echo "It's the fourth Thursday of the month" + # last thursday of the month will always be within 6 days of the last day of the month + # $last_day_cutoff=(# days in this month - 6) + elif [[ "$day_of_month" -ge "$last_day_cutoff" ]]; then + echo "It's the last Thursday of the month" echo "bool=true" >> "${GITHUB_OUTPUT}" else echo "It's another Thursday of the month" From 20651d58e9ae24882474cbca2c557785a81a2ff6 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Tue, 5 Mar 2024 12:04:44 +0000 Subject: [PATCH 780/812] Splunk docs polishing --- docs/framework-splunk_otel_java_agent.md | 38 +++++++++++++----------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/docs/framework-splunk_otel_java_agent.md b/docs/framework-splunk_otel_java_agent.md index e8b438376b..f6c0bf2a5f 100644 --- a/docs/framework-splunk_otel_java_agent.md +++ b/docs/framework-splunk_otel_java_agent.md @@ -1,9 +1,8 @@ # Splunk Distribution of OpenTelemetry Java Instrumentation -The Splunk OpenTelemetry Java Agent buildpack framework will cause an application to be automatically instrumented -with the [Splunk distribution of OpenTelemetry Java Instrumentation](https://github.com/signalfx/splunk-otel-java). - -Trace data will be sent directly to Splunk Observability Cloud. +This buildpack framework automatically instruments your Java application +with the [Splunk distribution of OpenTelemetry Java Instrumentation](https://github.com/signalfx/splunk-otel-java) +to send trace data to Splunk Observability Cloud.
Detection CriterionExistence of a spring-boot-3*.jar file in the application directory or a `Spring-Boot-Version: 3.*` manifest entryExistence of a `Spring-Boot-Version: 3.*` manifest entry No existing `java-cfenv` library found
@@ -16,15 +15,18 @@ Trace data will be sent directly to Splunk Observability Cloud.
-Tags are printed to standard output by the buildpack detect script +The buildpack detect script prints tags to standard output. ## User-Provided Service -Users are currently expected to `create-user-provided-service` (cups) of the collector -and bind it to their application. The service MUST contain the string `splunk-o11y`. + +Provide your own "user provided service" (cups) instance and bind +it to your application. + +The service name MUST contain the string `splunk-o11y`. For example, to create a service named `splunk-o11y` that represents Observability Cloud -realm `us0` and represents a user environment named `cf-demo`, you could use the following +realm `us0` and represents a user environment named `cf-demo`, use the following commands: ``` @@ -34,27 +36,29 @@ $ cf bind-service myApp splunk-o11y $ cf restage myApp ``` -The `credential` field of the service should provide these entries: +Provide the following values using the `credential` field of the service: | Name | Required? | Description |------------------------|-----------| ----------- -| `splunk.access.token` | Yes | The Splunk [org access token](https://docs.splunk.com/observability/admin/authentication-tokens/org-tokens.html). -| `splunk.realm` | Yes | The Splunk realm where data will be sent. This is commonly `us0` or `eu0` etc. -| `otel.*` or `splunk.*` | Optional | All additional credentials starting with these prefixes will be appended to the application's JVM arguments as system properties. +| `splunk.access.token` | Yes | Splunk [org access token](https://docs.splunk.com/observability/admin/authentication-tokens/org-tokens.html). +| `splunk.realm` | Yes | Splunk realm where data will be sent. This is commonly `us0`, `eu0`, and so on. See [Available regions or realms](https://docs.splunk.com/observability/en/get-started/service-description.html#available-regions-or-realms) for more information. +| `otel.*` or `splunk.*` | Optional | All additional credentials starting with these prefixes are appended to the application's JVM arguments as system properties. ### Choosing a version -Most users should skip this and simply use the latest version of the agent available (the default). -To override the default and choose a specific version, you can use the `JBP_CONFIG_*` mechanism +To override the default and choose a specific version, use the `JBP_CONFIG_*` mechanism and set the `JBP_CONFIG_SPLUNK_OTEL_JAVA_AGENT` environment variable for your application. -For example, to use version 1.16.0 of the Splunk OpenTelemetry Java Instrumentation, you -could run: +For example, to use version 1.16.0 of the Splunk OpenTelemetry Java Instrumentation, run: + ``` $ cf set-env testapp JBP_CONFIG_SPLUNK_OTEL_JAVA_AGENT '{version: 1.16.0}' ``` - + +In most cases you can use the latest or default version of the agent available. + # Additional Resources * [Splunk Observability](https://www.splunk.com/en_us/products/observability.html) +* [Official documentation of the Splunk Java agent](https://docs.splunk.com/observability/en/gdi/get-data-in/application/java/get-started.html) * [Splunk Distribution of OpenTelemetry Java](https://github.com/signalfx/splunk-otel-java) on GitHub From 5272f715e1561b6784c9c34df9f5ff7e1589a887 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Tue, 5 Mar 2024 15:47:48 +0000 Subject: [PATCH 781/812] packaging update --- .gitignore | 1 + config/packaging.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 814b1fb86c..75d6b50bdb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .idea/tasks.xml .idea/workspace.xml .yardoc +.DS_Store build/ doc .envrc diff --git a/config/packaging.yml b/config/packaging.yml index 001dc0be88..40d547077c 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -200,4 +200,4 @@ tomcat: your_kit_profiler: name: YourKit Profiler - release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2023_5_builds.jsp)' + release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2023_9_builds.jsp)' From f7f64672b66f42ae0df0956acc8027d18e208af0 Mon Sep 17 00:00:00 2001 From: Sophie Wigmore Date: Mon, 18 Mar 2024 14:39:57 -0400 Subject: [PATCH 782/812] release-reminder fix --- .github/workflows/release-reminder.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/release-reminder.yml b/.github/workflows/release-reminder.yml index 304d4468cb..ff3c26928d 100644 --- a/.github/workflows/release-reminder.yml +++ b/.github/workflows/release-reminder.yml @@ -55,7 +55,6 @@ jobs: uses: actions/checkout@v3 with: token: ${{ secrets.CF_BOT_GITHUB_TOKEN }} - ref: develop fetch-depth: 0 - name: Get Latest Version @@ -82,11 +81,6 @@ jobs: The ideal release date window for this buildpack starts on: ${{ steps.date.outputs.today }} and ends on ${{ steps.date.outputs.window_close_date }}. - ${{ steps.php-specific.outputs.task }} - * See [diff from latest version]("https://github.com/${{ github.repository }}/compare/${{ steps.latest-version.outputs.val }}..develop") and validate if a release is required. - * Make sure the latest commit on `develop` has passed tests on the [CI](https://buildpacks.ci.cf-app.com/teams/main/pipelines/${{ github.event.repository.name }}) - * Refer [release instructions](https://github.com/pivotal-cf/tanzu-buildpacks/wiki/Releasing-CF-Buildpacks). (private link) - - name: Add issue to project id: issue-to-proj uses: paketo-buildpacks/github-config/actions/issue/add-to-project@main From 4a0ebd17b829cefc9b61940c201b6fd427449602 Mon Sep 17 00:00:00 2001 From: Scott Gai <7351279+scottgai@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:42:07 +1100 Subject: [PATCH 783/812] add aws-mysql-jdbc*.jar --- lib/java_buildpack/framework/maria_db_jdbc.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/java_buildpack/framework/maria_db_jdbc.rb b/lib/java_buildpack/framework/maria_db_jdbc.rb index 712b367804..7a16997ce8 100644 --- a/lib/java_buildpack/framework/maria_db_jdbc.rb +++ b/lib/java_buildpack/framework/maria_db_jdbc.rb @@ -46,7 +46,7 @@ def supports? private def driver? - %w[mariadb-java-client*.jar mysql-connector-j*.jar].any? do |candidate| + %w[mariadb-java-client*.jar mysql-connector-j*.jar aws-mysql-jdbc*.jar].any? do |candidate| (@application.root + '**' + candidate).glob.any? end end From 2c1957ad5962360aa80e3413255625c6101ad892 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 20 Mar 2024 09:40:27 +0000 Subject: [PATCH 784/812] contrast agent release note update --- config/packaging.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/packaging.yml b/config/packaging.yml index 40d547077c..a789bd3bb7 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -50,7 +50,7 @@ container_security_provider: contrast_security_agent: name: Contrast Security Agent - release_notes: '[Release Notes](https://docs.contrastsecurity.com/en/java-agent-release-notes.html)' + release_notes: '[Release Notes](https://docs.contrastsecurity.com/en/java-agent-release-notes-and-archive.html)' datadog_javaagent: name: Datadog APM Javaagent From bab1ed3b83fad862a4e34e1d68ff73f9e0306624 Mon Sep 17 00:00:00 2001 From: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> Date: Thu, 9 May 2024 13:18:40 +0100 Subject: [PATCH 785/812] Update release-reminder.yml --- .github/workflows/release-reminder.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-reminder.yml b/.github/workflows/release-reminder.yml index ff3c26928d..ad47caae1d 100644 --- a/.github/workflows/release-reminder.yml +++ b/.github/workflows/release-reminder.yml @@ -23,12 +23,12 @@ jobs: last_day_cutoff=$(expr $(date -d "-$(date +%d) days month" +%d) - 6) # Check if it's the second or last Thursday of the month # second thursday of the month will always be between day 8 and 14 (inclusive) - if [[ "$day_of_month" -ge "8" && "$day_of_month" -le "14" ]]; then + if [ "$day_of_month" -ge "8" && "$day_of_month" -le "14" ]; then echo "It's the second Thursday of the month" echo "bool=true" >> "${GITHUB_OUTPUT}" # last thursday of the month will always be within 6 days of the last day of the month # $last_day_cutoff=(# days in this month - 6) - elif [[ "$day_of_month" -ge "$last_day_cutoff" ]]; then + elif [ "$day_of_month" -ge "$last_day_cutoff" ]; then echo "It's the last Thursday of the month" echo "bool=true" >> "${GITHUB_OUTPUT}" else From 1bcc6d71267a522947132681129e47176569c117 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Fri, 10 May 2024 11:49:31 +0100 Subject: [PATCH 786/812] updates to various release-note URLs --- config/packaging.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index a789bd3bb7..ca119127fc 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -24,7 +24,7 @@ agent: app_dynamics_agent: name: AppDynamics Agent - release_notes: '[Release Notes](https://docs.appdynamics.com/4.5.x/en/product-and-release-announcements/release-notes/language-agent-notes/java-agent-notes)' + release_notes: '[Release Notes](https://docs.appdynamics.com/appd/onprem/24.x/latest/en/product-and-release-announcements/release-notes)' azure_application_insights_agent: name: Azure Application Insights Agent @@ -92,23 +92,23 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u402b7/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u412b9/general/release-notes/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.22b12/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.23b10/general/release-notes/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.10b13/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.11b10/general/release-notes/)' jre-21: name: OpenJDK JRE 21 cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.2b14/general/release-notes/)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.3b10/general/release-notes/)' jrebel_agent: name: JRebel Agent @@ -200,4 +200,4 @@ tomcat: your_kit_profiler: name: YourKit Profiler - release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2023_9_builds.jsp)' + release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2024_3_builds.jsp)' From b7a2802ccd4a8718cb094f0d1d19cfcefe7430dc Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 4 Apr 2024 14:32:56 +0100 Subject: [PATCH 787/812] Adds support for Tomcat 10.1 alongside 9 --- config/packaging.yml | 7 ++++++- config/tomcat.yml | 3 +++ rakelib/dependency_cache_task.rb | 14 ++++++++++++++ rakelib/package.rb | 3 +++ rakelib/utils.rb | 15 +++++++++++++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/config/packaging.yml b/config/packaging.yml index a789bd3bb7..915f9df6d7 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -194,10 +194,15 @@ takipi_agent: release_notes: '[Release Notes](https://doc.overops.com/docs/whats-new)' tomcat: - name: Tomcat + name: Tomcat 9 cve_notes: '[Security](https://tomcat.apache.org/security-9.html)' release_notes: '[ChangeLog](https://tomcat.apache.org/tomcat-9.0-doc/changelog.html)' +tomcat-10: + name: Tomcat 10.1 + cve_notes: '[Security](https://tomcat.apache.org/security-10.html)' + release_notes: '[ChangeLog](https://tomcat.apache.org/tomcat-10.1-doc/changelog.html)' + your_kit_profiler: name: YourKit Profiler release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2023_9_builds.jsp)' diff --git a/config/tomcat.yml b/config/tomcat.yml index c05fcdeb09..ac2df4789a 100644 --- a/config/tomcat.yml +++ b/config/tomcat.yml @@ -17,6 +17,9 @@ --- tomcat: version: 9.+ + version_lines: + - 9.+ + - 10.1.+ repository_root: "{default.repository.root}/tomcat" context_path: external_configuration_enabled: false diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 12d3d54845..421f0df323 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -164,6 +164,9 @@ def pin_version(old_configuration, version) if Utils::VersionUtils.openjdk_jre? old_configuration rake_output_message "Pinning JRE #{sub_component_id || component_id} version to #{version}" pin_jre(component_id, sub_component_id, version) + elsif Utils::VersionUtils.tomcat? old_configuration + rake_output_message "Pinning Tomcat #{sub_component_id || component_id} version to #{version}" + pin_tomcat(component_id, sub_component_id, version) else rake_output_message "Pinning #{sub_component_id || component_id} version to #{version}" pin_component(component_id, sub_component_id, version) @@ -187,6 +190,17 @@ def pin_jre(component_id, sub_component_id, version) JavaBuildpack::Util::ConfigurationUtils.write(component_id, configuration_to_update) end + def pin_tomcat(component_id, sub_component_id, version) + # update configuration file, pin version & version lines + configuration_to_update = JavaBuildpack::Util::ConfigurationUtils.load(component_id, false, true) + update_configuration(configuration_to_update, version, sub_component_id) + configuration_to_update['tomcat']['version_lines'].each_with_index do |version_pattern, index| + configuration_to_update['tomcat']['version_lines'][index] = version \ + if Utils::VersionUtils.version_matches?(version_pattern, [version]) + end + JavaBuildpack::Util::ConfigurationUtils.write(component_id, configuration_to_update) + end + def update_configuration(config, version, sub_component) if sub_component.nil? config['version'] = version diff --git a/rakelib/package.rb b/rakelib/package.rb index 5e38fbfbe1..f3948ee189 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -38,6 +38,9 @@ def configurations(component_id, configuration, sub_component_id = nil) Utils::VersionUtils.java_version_lines(configuration, configurations) \ if Utils::VersionUtils.openjdk_jre? configuration + Utils::VersionUtils.tomcat_version_lines(configuration, configurations) \ + if Utils::VersionUtils.tomcat? configuration + configurations << configuration else configuration.each { |k, v| configurations << configurations(component_id, v, k) if v.is_a? Hash } diff --git a/rakelib/utils.rb b/rakelib/utils.rb index 98a40fef8f..0202066f25 100644 --- a/rakelib/utils.rb +++ b/rakelib/utils.rb @@ -39,6 +39,10 @@ def openjdk_jre?(configuration) configuration['component_id'].end_with?('_jre') && configuration['sub_component_id'].start_with?('jre') end + def tomcat?(configuration) + configuration['component_id'].end_with?('tomcat') && configuration['sub_component_id'].start_with?('tomcat') + end + def java_version_lines(configuration, configurations) configuration['version_lines'].each do |v| next if version_line_matches?(configuration, v) @@ -50,6 +54,17 @@ def java_version_lines(configuration, configurations) end end + def tomcat_version_lines(configuration, configurations) + configuration['version_lines'].each do |v| + next if version_line_matches?(configuration, v) + + c1 = configuration.clone + c1['sub_component_id'] = "tomcat-#{v.split('.')[0]}" + c1['version'] = v + configurations << c1 + end + end + def version_line_matches?(configuration, v) return true if v == configuration['version'] return false if version_wildcard? v From 5fb2f95a917fa34bb2337f7004fef3bb34861488 Mon Sep 17 00:00:00 2001 From: Hans-Joachim Kliemeck Date: Wed, 29 May 2024 09:38:58 +0200 Subject: [PATCH 788/812] harmonization of gorouter -> java app communication --- resources/tomcat/conf/server.xml | 2 +- .../.java-buildpack/tomcat/conf/server.xml | 2 +- spec/fixtures/container_tomcat_geode_store_server_after.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/tomcat/conf/server.xml b/resources/tomcat/conf/server.xml index a75866fb1a..b147786ba9 100644 --- a/resources/tomcat/conf/server.xml +++ b/resources/tomcat/conf/server.xml @@ -19,7 +19,7 @@ - + diff --git a/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/server.xml b/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/server.xml index f6f4bd0e52..cf1f9f23ee 100644 --- a/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/server.xml +++ b/spec/fixtures/container_tomcat_geode_store/.java-buildpack/tomcat/conf/server.xml @@ -18,7 +18,7 @@ - + diff --git a/spec/fixtures/container_tomcat_geode_store_server_after.xml b/spec/fixtures/container_tomcat_geode_store_server_after.xml index 7796cbfc53..df95030a49 100644 --- a/spec/fixtures/container_tomcat_geode_store_server_after.xml +++ b/spec/fixtures/container_tomcat_geode_store_server_after.xml @@ -17,7 +17,7 @@ --> - + From c99aa33bc11455a1f0883022ec7366ce52bfdfb0 Mon Sep 17 00:00:00 2001 From: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:41:40 +0100 Subject: [PATCH 789/812] Update Dockerfile --- ci/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/Dockerfile b/ci/Dockerfile index d4ee0c6d55..cf7a4047bf 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -12,6 +12,7 @@ RUN apt-get update && apt-get install -y \ python \ zip \ zlib1g-dev \ + openjdk-17 \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* From 84f07503ba909df0e6b323abe4d167392c90258d Mon Sep 17 00:00:00 2001 From: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:52:28 +0100 Subject: [PATCH 790/812] Update Dockerfile --- ci/Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci/Dockerfile b/ci/Dockerfile index cf7a4047bf..2fa8d6c310 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,6 +1,9 @@ ARG base_image=ubuntu:bionic FROM ${base_image} +RUN wget -q -O - https://download.bell-sw.com/pki/GPG-KEY-bellsoft | sudo apt-key add - +RUN echo "deb [arch=amd64] https://apt.bell-sw.com/ stable main" | sudo tee /etc/apt/sources.list.d/bellsoft.list + RUN apt-get update && apt-get install -y \ build-essential \ curl \ @@ -12,7 +15,7 @@ RUN apt-get update && apt-get install -y \ python \ zip \ zlib1g-dev \ - openjdk-17 \ + bellsoft-java17 \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* From fa3da8a3799afe4a29df1eb33c9ff9fd73286051 Mon Sep 17 00:00:00 2001 From: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:57:08 +0100 Subject: [PATCH 791/812] Update Dockerfile --- ci/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ci/Dockerfile b/ci/Dockerfile index 2fa8d6c310..a6e86ee06b 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,8 +1,10 @@ ARG base_image=ubuntu:bionic FROM ${base_image} -RUN wget -q -O - https://download.bell-sw.com/pki/GPG-KEY-bellsoft | sudo apt-key add - -RUN echo "deb [arch=amd64] https://apt.bell-sw.com/ stable main" | sudo tee /etc/apt/sources.list.d/bellsoft.list +RUN apt-get update && apt-get install -y wget + +RUN wget -q -O - https://download.bell-sw.com/pki/GPG-KEY-bellsoft | apt-key add - +RUN echo "deb [arch=amd64] https://apt.bell-sw.com/ stable main" | tee /etc/apt/sources.list.d/bellsoft.list RUN apt-get update && apt-get install -y \ build-essential \ From e2dd4eb641fd14b9978b1a714d7bcbf9b9a2ce00 Mon Sep 17 00:00:00 2001 From: David O'Sullivan <31728678+pivotal-david-osullivan@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:01:38 +0100 Subject: [PATCH 792/812] Update Dockerfile --- ci/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile b/ci/Dockerfile index a6e86ee06b..79a666b0c0 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,7 +1,7 @@ ARG base_image=ubuntu:bionic FROM ${base_image} -RUN apt-get update && apt-get install -y wget +RUN apt-get update && apt-get install -y wget gnupg RUN wget -q -O - https://download.bell-sw.com/pki/GPG-KEY-bellsoft | apt-key add - RUN echo "deb [arch=amd64] https://apt.bell-sw.com/ stable main" | tee /etc/apt/sources.list.d/bellsoft.list From fca1d45b0185459681f4711afef45f9c60b54c3e Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 24 Oct 2024 15:51:04 +0100 Subject: [PATCH 793/812] Java Oct release notes --- config/packaging.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index 12b955c2a3..57697632c3 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -92,23 +92,23 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u412b9/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u432b7/general/release-notes/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.23b10/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.25b11/general/release-notes/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.11b10/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.13b12/general/release-notes/)' jre-21: name: OpenJDK JRE 21 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.3b10/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2024.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.5b11/general/release-notes/)' jrebel_agent: name: JRebel Agent From 87463d183625284c9bdf0e9c37f26a13960df5a3 Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Thu, 7 Nov 2024 09:13:18 +0100 Subject: [PATCH 794/812] adds multi-tech support to Dynatrace OneAgent integration --- .../framework/dynatrace_one_agent.rb | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 23206f26d2..d0f7041e6d 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -85,6 +85,8 @@ def supports? private + ADDTECHNOLOGIES = 'addtechnologies' + APIURL = 'apiurl' APITOKEN = 'apitoken' @@ -113,12 +115,12 @@ def supports? SKIP_ERRORS = 'skiperrors' - private_constant :APIURL, :APITOKEN, :ENABLE_FIPS, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, :DT_NETWORK_ZONE, - :DT_LOGSTREAM, :DT_TENANT, :DT_TENANTTOKEN, :LD_PRELOAD, :ENVIRONMENTID, :FILTER, :NETWORKZONE, - :SKIP_ERRORS + private_constant :ADDTECHNOLOGIES, :APIURL, :APITOKEN, :ENABLE_FIPS, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, + :DT_NETWORK_ZONE, :DT_LOGSTREAM, :DT_TENANT, :DT_TENANTTOKEN, :LD_PRELOAD, :ENVIRONMENTID, + :FILTER, :NETWORKZONE, :SKIP_ERRORS def agent_download_url - download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?include=java" \ + download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?#{technologies(credentials)}" \ '&bitness=64' \ "&Api-Token=#{credentials[APITOKEN]}" @@ -127,6 +129,18 @@ def agent_download_url ['latest', download_uri] end + def technologies(credentials) + code_modules = "include=java" + if not credentials[ADDTECHNOLOGIES].empty? + credentials[ADDTECHNOLOGIES].split(",").each do |tech| + code_modules += "&include=#{tech}" + end + end + return code_modules + end + + end + def agent_manifest JSON.parse(File.read(@droplet.sandbox + 'manifest.json')) end From b7aed58669729496c0af714d6397fe599829d374 Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Thu, 7 Nov 2024 10:30:37 +0100 Subject: [PATCH 795/812] remove faulty leftover end statement --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index d0f7041e6d..072ff2b253 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -116,7 +116,7 @@ def supports? SKIP_ERRORS = 'skiperrors' private_constant :ADDTECHNOLOGIES, :APIURL, :APITOKEN, :ENABLE_FIPS, :DT_APPLICATION_ID, :DT_CONNECTION_POINT, - :DT_NETWORK_ZONE, :DT_LOGSTREAM, :DT_TENANT, :DT_TENANTTOKEN, :LD_PRELOAD, :ENVIRONMENTID, + :DT_NETWORK_ZONE, :DT_LOGSTREAM, :DT_TENANT, :DT_TENANTTOKEN, :LD_PRELOAD, :ENVIRONMENTID, :FILTER, :NETWORKZONE, :SKIP_ERRORS def agent_download_url @@ -139,8 +139,6 @@ def technologies(credentials) return code_modules end - end - def agent_manifest JSON.parse(File.read(@droplet.sandbox + 'manifest.json')) end From d17f67c13c0730faf65f6753be16abde63080839 Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Fri, 8 Nov 2024 08:06:50 +0100 Subject: [PATCH 796/812] adds debug output for fixing faulty logging --- lib/java_buildpack/component/base_component.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 2f43e3d565..2337f2ed86 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -89,6 +89,7 @@ def release # @return [Void] def download(version, uri, name = @component_name) download_start_time = Time.now + print "FIXMEDEBUG #{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri} " print "#{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri.sanitize_uri} " JavaBuildpack::Util::Cache::CacheFactory.create.get(uri) do |file, downloaded| From b1395cad8a2502cf1af4aabdbd304b0a9ab1a407 Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Fri, 8 Nov 2024 12:41:21 +0100 Subject: [PATCH 797/812] refactors url sanitizer to fix bug where it removs multiple include parameters --- lib/java_buildpack/util/sanitizer.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index 6f1f5de2df..e2826eb4eb 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -36,11 +36,13 @@ def handle_params(params) query_params = '' - params.each do |key, _| - params[key] = '***' if key.match(keywords) - query_params += key + '=' + params[key] + '&' + params.split("&").each do |single_param| + k, v = single_param.split("=") + if k.match(keywords) + v = "***" + end + query_params += k + '=' +v + '&' end - query_params end @@ -53,8 +55,7 @@ def sanitize_uri rich_uri.password = nil if rich_uri.query - params = (URI.decode_www_form rich_uri.query).to_h - query_params = handle_params(params) + query_params = handle_params(rich_uri.query) rich_uri.query = query_params.chop end From a87a2e597b9335f7391061e7801e87ff6533e53c Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Fri, 8 Nov 2024 12:46:47 +0100 Subject: [PATCH 798/812] removes debug output again --- lib/java_buildpack/component/base_component.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/java_buildpack/component/base_component.rb b/lib/java_buildpack/component/base_component.rb index 2337f2ed86..2f43e3d565 100644 --- a/lib/java_buildpack/component/base_component.rb +++ b/lib/java_buildpack/component/base_component.rb @@ -89,7 +89,6 @@ def release # @return [Void] def download(version, uri, name = @component_name) download_start_time = Time.now - print "FIXMEDEBUG #{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri} " print "#{'----->'.red.bold} Downloading #{name.blue.bold} #{version.to_s.blue} from #{uri.sanitize_uri} " JavaBuildpack::Util::Cache::CacheFactory.create.get(uri) do |file, downloaded| From 08e611198d83ae87164302f434ad7be5ea141638 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 4 Dec 2024 16:16:36 +0000 Subject: [PATCH 799/812] bumps Ruby to 3.2 with relevant changes --- config/packaging.yml | 4 ++++ config/ruby.yml | 2 +- lib/java_buildpack/util/filtering_pathname.rb | 8 ++------ .../util/filtering_pathname_spec.rb | 18 ------------------ 4 files changed, 7 insertions(+), 25 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index 57697632c3..9d7dd2cb9c 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -170,6 +170,10 @@ redis_store: riverbed_appinternals_agent: name: Riverbed Appinternals Agent +ruby: + name: Ruby + release_notes: 'https://www.ruby-lang.org/en/downloads/releases' + sealights_agent: name: SeaLights Agent diff --git a/config/ruby.yml b/config/ruby.yml index 40287d4227..94541f7ee4 100644 --- a/config/ruby.yml +++ b/config/ruby.yml @@ -15,5 +15,5 @@ # Configuration for Ruby --- -version: 3.1.+ +version: 3.2.+ repository_root: https://raw.githubusercontent.com/cloudfoundry/ruby-buildpack/master/java-index diff --git a/lib/java_buildpack/util/filtering_pathname.rb b/lib/java_buildpack/util/filtering_pathname.rb index 133b7987cb..dd04d77a7e 100644 --- a/lib/java_buildpack/util/filtering_pathname.rb +++ b/lib/java_buildpack/util/filtering_pathname.rb @@ -83,10 +83,6 @@ def ===(other) @pathname === comparison_target(other) # rubocop:disable Style/CaseEquality end - # Dispatch superclass methods via method_missing. - undef_method :taint - undef_method :untaint - # @see Pathname. def +(other) filtered_pathname(@pathname + other) @@ -104,7 +100,7 @@ def entries # @see Pathname. def open(mode = nil, *args, **kwargs, &block) - check_mutable if mode =~ /[wa]/ + check_mutable if /[wa]/ =~ mode.to_s delegate.open(mode, *args, **kwargs, &block) end @@ -150,7 +146,7 @@ def glob(flags = 0) private MUTATORS = %i[chmod chown delete lchmod lchown make_link make_symlink mkdir mkpath rename rmdir rmtree taint - unlink untaint].to_set.freeze + unlink].to_set.freeze private_constant :MUTATORS diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index 93cd3634e1..730cf66be6 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -380,24 +380,6 @@ mutable_target.unlink end - it 'raises error if untaint is called on an immutable instance' do - expect { immutable_target.untaint }.to raise_error(/FilteringPathname is immutable/) - end - - it 'delegates if untaint is called on a mutable instance' do - allow(app_dir).to receive(:untaint) - mutable_target.untaint - end - - it 'raises error if taint is called on an immutable instance' do - expect { immutable_target.taint }.to raise_error(/FilteringPathname is immutable/) - end - - it 'delegates if taint is called on a mutable instance' do - allow(app_dir).to receive(:taint) - mutable_target.taint - end - it 'raises error if mkpath is called on an immutable instance' do expect { immutable_target.mkpath }.to raise_error(/FilteringPathname is immutable/) end From 49ca7ea094a85ad402599925b67ea67b8be4eabc Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Mon, 27 Jan 2025 10:19:36 +0100 Subject: [PATCH 800/812] adds documentation about new addtechnologies" parameter --- docs/framework-dynatrace_one_agent.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/framework-dynatrace_one_agent.md b/docs/framework-dynatrace_one_agent.md index 6a88ef5ac7..0cbeaf3866 100644 --- a/docs/framework-dynatrace_one_agent.md +++ b/docs/framework-dynatrace_one_agent.md @@ -31,6 +31,7 @@ The credential payload of the service may contain the following entries: | `networkzone` | (Optional) Network zones are Dynatrace entities that represent your network structure. They help you to route the traffic efficiently, avoiding unnecessary traffic across data centers and network regions. Enter the network zone you wish to pass to the server during the OneAgent Download. | `skiperrors` | (Optional) The errors during agent download are skipped and the injection is disabled. Use this option at your own risk. Possible values are 'true' and 'false'. This option is disabled by default! | `enablefips`| (Optional) Enables the use of [FIPS 140 cryptographic algorithms](https://docs.dynatrace.com/docs/shortlink/oneagentctl#fips-140). Possible values are 'true' and 'false'. This option is disabled by default! +| addtechnologies | (Optional) Adds additional OneAgent code-modules via a comma-separated list. See [supported values](https://docs.dynatrace.com/docs/dynatrace-api/environment-api/deployment/oneagent/download-oneagent-version#parameters) in the "included" row| ## Configuration For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. From c0f13d5b414d16a675e5daae157dfb26f33fd5ac Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 5 Feb 2025 12:49:15 +0000 Subject: [PATCH 801/812] polishing dynatrace enhancement --- lib/java_buildpack/framework/dynatrace_one_agent.rb | 11 ++++++----- lib/java_buildpack/util/sanitizer.rb | 10 ++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/java_buildpack/framework/dynatrace_one_agent.rb b/lib/java_buildpack/framework/dynatrace_one_agent.rb index 072ff2b253..b4a9070575 100644 --- a/lib/java_buildpack/framework/dynatrace_one_agent.rb +++ b/lib/java_buildpack/framework/dynatrace_one_agent.rb @@ -120,7 +120,8 @@ def supports? :FILTER, :NETWORKZONE, :SKIP_ERRORS def agent_download_url - download_uri = "#{api_base_url(credentials)}/v1/deployment/installer/agent/unix/paas/latest?#{technologies(credentials)}" \ + download_uri = "#{api_base_url(credentials)}" \ + "/v1/deployment/installer/agent/unix/paas/latest?#{technologies(credentials)}" \ '&bitness=64' \ "&Api-Token=#{credentials[APITOKEN]}" @@ -130,13 +131,13 @@ def agent_download_url end def technologies(credentials) - code_modules = "include=java" - if not credentials[ADDTECHNOLOGIES].empty? - credentials[ADDTECHNOLOGIES].split(",").each do |tech| + code_modules = 'include=java' + if credentials.key?(ADDTECHNOLOGIES) + credentials[ADDTECHNOLOGIES].split(',').each do |tech| code_modules += "&include=#{tech}" end end - return code_modules + code_modules end def agent_manifest diff --git a/lib/java_buildpack/util/sanitizer.rb b/lib/java_buildpack/util/sanitizer.rb index e2826eb4eb..50a2947cd2 100644 --- a/lib/java_buildpack/util/sanitizer.rb +++ b/lib/java_buildpack/util/sanitizer.rb @@ -36,12 +36,10 @@ def handle_params(params) query_params = '' - params.split("&").each do |single_param| - k, v = single_param.split("=") - if k.match(keywords) - v = "***" - end - query_params += k + '=' +v + '&' + params.split('&').each do |single_param| + k, v = single_param.split('=') + v = '***' if k.match(keywords) + query_params += k + '=' + v + '&' end query_params end From e29ccd6e725da786390ec0c9b32414badd6325d6 Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Wed, 5 Feb 2025 16:17:24 +0000 Subject: [PATCH 802/812] release note updates --- config/packaging.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index 9d7dd2cb9c..e0054175ce 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -92,23 +92,23 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u432b7/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2025.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u442b7/general/release-notes/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.25b11/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2025.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.26b9/general/release-notes/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.13b12/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2025.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.14b10/general/release-notes/)' jre-21: name: OpenJDK JRE 21 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuoct2024.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.5b11/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2025.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.6b10/general/release-notes/)' jrebel_agent: name: JRebel Agent @@ -209,4 +209,4 @@ tomcat-10: your_kit_profiler: name: YourKit Profiler - release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2024_3_builds.jsp)' + release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2024_9_builds.jsp)' From 996ef67664e41ad0fc3e53d30b2238ac28897d21 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Thu, 27 Feb 2025 12:50:59 +0100 Subject: [PATCH 803/812] Update link to SapMachine repository --- config/sap_machine_jre.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sap_machine_jre.yml b/config/sap_machine_jre.yml index ab3598754a..0c372cc4d7 100644 --- a/config/sap_machine_jre.yml +++ b/config/sap_machine_jre.yml @@ -21,7 +21,7 @@ jre: version_lines: - 11.+ - 17.+ - repository_root: "https://sap.github.io/SapMachine/assets/cf/jre/{platform}/{architecture}" + repository_root: "https://sapmachine.io/assets/cf/jre/{platform}/{architecture}" jvmkill_agent: version: 1.+ repository_root: "{default.repository.root}/jvmkill/{platform}/{architecture}" From 25686e6b6d13d6540c6938e50f15d18fb524933f Mon Sep 17 00:00:00 2001 From: David O'Sullivan Date: Thu, 8 May 2025 16:26:35 +0100 Subject: [PATCH 804/812] release note updates --- config/packaging.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/config/packaging.yml b/config/packaging.yml index e0054175ce..db047e5ef9 100644 --- a/config/packaging.yml +++ b/config/packaging.yml @@ -92,23 +92,23 @@ jprofiler_profiler: jre: name: OpenJDK JRE 8 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2025.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u442b7/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2025.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/8u452b11/general/release-notes/)' jre-11: name: OpenJDK JRE 11 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2025.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.26b9/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2025.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/11.0.27b9/general/release-notes/)' jre-17: name: OpenJDK JRE 17 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2025.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.14b10/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2025.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/17.0.15b10/general/release-notes/)' jre-21: name: OpenJDK JRE 21 - cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpujan2025.html#AppendixJAVA)' - release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.6b10/general/release-notes/)' + cve_notes: '[Risk Matrix](https://www.oracle.com/security-alerts/cpuapr2025.html#AppendixJAVA)' + release_notes: '[Release Notes](https://docs.bell-sw.com/liberica-jdk/21.0.7b9/general/release-notes/)' jrebel_agent: name: JRebel Agent @@ -209,4 +209,4 @@ tomcat-10: your_kit_profiler: name: YourKit Profiler - release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2024_9_builds.jsp)' + release_notes: '[Release Notes](https://www.yourkit.com/download/yjp_2025_3_builds.jsp)' From 7975774ec6f75bad609a2b21531569b29ba06de7 Mon Sep 17 00:00:00 2001 From: kiril-keranov <114745615+kiril-keranov@users.noreply.github.com> Date: Thu, 11 Sep 2025 18:15:23 +0300 Subject: [PATCH 805/812] Update jprofiler_profiler.yml --- config/jprofiler_profiler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/jprofiler_profiler.yml b/config/jprofiler_profiler.yml index d741f2f611..e48294a00c 100644 --- a/config/jprofiler_profiler.yml +++ b/config/jprofiler_profiler.yml @@ -15,7 +15,7 @@ # JMX configuration --- -version: 13.+ +version: 15.+ repository_root: https://download.run.pivotal.io/jprofiler enabled: false nowait: true From 6bbee1cef7e1618453172e57d42acaa3f777211d Mon Sep 17 00:00:00 2001 From: ramonskie Date: Mon, 17 Nov 2025 23:01:13 +0100 Subject: [PATCH 806/812] Migrate from Ruby 2.5.9 to Ruby 3.4.7 with Psych 4.0+ compatibility Update buildpack to use Ruby 3.4.7, addressing YAML loading changes in Psych 4.0+, adding required standard library gems, and modernizing Ruby syntax. All core utility specs (266 examples) pass successfully. Key changes: - Update YAML.load_file calls to use permitted_classes and aliases parameters - Add Psych::DisallowedClass to exception handling - Include base64, bigdecimal, digest, set, and tmpdir gems explicitly - Adopt endless range syntax (tokens[1..] vs tokens[1..-1]) - Remove Ruby 2.x version-specific test code - Modernize RuboCop configuration for rubocop-rspec --- .rubocop.yml | 7 +++-- .ruby-version | 2 +- Gemfile | 7 +++++ Gemfile.lock | 12 +++++++++ .../framework/multi_buildpack.rb | 2 +- .../repository/repository_index.rb | 2 +- .../util/configuration_utils.rb | 6 ++--- lib/java_buildpack/util/tokenized_version.rb | 10 ++----- .../util/cache/download_cache_spec.rb | 26 ++----------------- .../util/filtering_pathname_spec.rb | 6 ++--- spec/spec_helper.rb | 1 + 11 files changed, 38 insertions(+), 43 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 17d9be63ca..49fe20c4f8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,6 @@ --- -require: rubocop-rspec +require: + - rubocop-rspec AllCops: NewCops: enable @@ -40,7 +41,9 @@ RSpec/ExampleLength: Max: 20 RSpec/ExpectOutput: Enabled: false -RSpec/FilePath: +RSpec/SpecFilePathFormat: + Enabled: false +RSpec/SpecFilePathSuffix: Enabled: false RSpec/MissingExampleGroupArgument: Enabled: false diff --git a/.ruby-version b/.ruby-version index 30f69e8cc5..2aa5131992 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.9 +3.4.7 diff --git a/Gemfile b/Gemfile index ec63e80628..e0334918f5 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,13 @@ source 'https://rubygems.org' +# Ruby 3.4+ standard library gems that need to be explicit +gem 'base64' +gem 'bigdecimal' +gem 'digest' +gem 'set' +gem 'tmpdir' + group :development do gem 'rake' gem 'redcarpet' diff --git a/Gemfile.lock b/Gemfile.lock index b3eb261a97..3e3741456a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,9 +4,13 @@ GEM addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) ast (2.4.2) + base64 (0.3.0) + bigdecimal (3.3.1) crack (0.4.5) rexml diff-lcs (1.5.0) + digest (3.2.1) + fileutils (1.8.0) hashdiff (1.0.1) parallel (1.22.1) parser (3.1.2.0) @@ -45,9 +49,12 @@ GEM rubocop (~> 1.19) ruby-progressbar (1.11.0) rubyzip (2.3.2) + set (1.1.2) tee (1.0.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) + tmpdir (0.3.1) + fileutils unicode-display_width (2.1.0) webmock (3.14.0) addressable (>= 2.8.0) @@ -61,14 +68,19 @@ PLATFORMS ruby DEPENDENCIES + base64 + bigdecimal + digest rake redcarpet rspec rubocop rubocop-rspec rubyzip + set tee terminal-table + tmpdir webmock yard diff --git a/lib/java_buildpack/framework/multi_buildpack.rb b/lib/java_buildpack/framework/multi_buildpack.rb index 1b0500d4a8..a1c97f7617 100644 --- a/lib/java_buildpack/framework/multi_buildpack.rb +++ b/lib/java_buildpack/framework/multi_buildpack.rb @@ -269,7 +269,7 @@ def add_system_properties(java_opts) end def config(config_file) - YAML.load_file(config_file) + YAML.load_file(config_file, permitted_classes: [Symbol], aliases: true) end def config_file(dep_directory) diff --git a/lib/java_buildpack/repository/repository_index.rb b/lib/java_buildpack/repository/repository_index.rb index 17529c351d..728ac7d480 100644 --- a/lib/java_buildpack/repository/repository_index.rb +++ b/lib/java_buildpack/repository/repository_index.rb @@ -39,7 +39,7 @@ def initialize(repository_root) .chomp('/') cache.get("#{canonical repository_root}#{INDEX_PATH}") do |file| - @index = YAML.load_file(file) + @index = YAML.load_file(file, permitted_classes: [Symbol], aliases: true) @logger.debug { @index } end end diff --git a/lib/java_buildpack/util/configuration_utils.rb b/lib/java_buildpack/util/configuration_utils.rb index 687ebaa7c7..9bad2b07fb 100644 --- a/lib/java_buildpack/util/configuration_utils.rb +++ b/lib/java_buildpack/util/configuration_utils.rb @@ -119,14 +119,14 @@ def header(file) def load_configuration(file, operator_provided, operator_var_name, user_provided, user_var_name, clean_nil_values, should_log) - configuration = YAML.load_file(file) + configuration = YAML.load_file(file, permitted_classes: [Symbol], aliases: true) logger.debug { "Configuration from #{file}: #{configuration}" } if should_log if operator_provided begin operator_provided_value = YAML.safe_load(operator_provided) configuration = merge_configuration(configuration, operator_provided_value, operator_var_name, should_log) - rescue Psych::SyntaxError => e + rescue Psych::SyntaxError, Psych::DisallowedClass => e raise "Default configuration value in environment variable #{operator_var_name} has invalid syntax: #{e}" end end @@ -135,7 +135,7 @@ def load_configuration(file, operator_provided, operator_var_name, user_provided begin user_provided_value = YAML.safe_load(user_provided) configuration = merge_configuration(configuration, user_provided_value, user_var_name, should_log) - rescue Psych::SyntaxError => e + rescue Psych::SyntaxError, Psych::DisallowedClass => e raise "User configuration value in environment variable #{user_var_name} has invalid syntax: #{e}" end logger.debug { "Configuration from #{file} modified with: #{user_provided}" } if should_log diff --git a/lib/java_buildpack/util/tokenized_version.rb b/lib/java_buildpack/util/tokenized_version.rb index dacd564d83..12e0e82dc0 100644 --- a/lib/java_buildpack/util/tokenized_version.rb +++ b/lib/java_buildpack/util/tokenized_version.rb @@ -93,10 +93,7 @@ def major_or_minor_and_tail(s) tokens = s.match(/^([^.]+)(?:\.(.*))?/) - # disable as we still have to support Ruby 2.5, remove & update when we drop Bionic support - # rubocop:disable Style/SlicingWithRange - major_or_minor, tail = tokens[1..-1] - # rubocop:enable Style/SlicingWithRange + major_or_minor, tail = tokens[1..] raise "Invalid major or minor version '#{major_or_minor}'" unless valid_major_minor_or_micro major_or_minor end @@ -113,10 +110,7 @@ def micro_and_qualifier(s) tokens = s.match(/^([^_]+)(?:_(.*))?/) - # disable as we still have to support Ruby 2.5, remove & update when we drop Bionic support - # rubocop:disable Style/SlicingWithRange - micro, qualifier = tokens[1..-1] - # rubocop:enable Style/SlicingWithRange + micro, qualifier = tokens[1..] raise "Invalid micro version '#{micro}'" unless valid_major_minor_or_micro micro raise "Invalid qualifier '#{qualifier}'" unless valid_qualifier qualifier diff --git a/spec/java_buildpack/util/cache/download_cache_spec.rb b/spec/java_buildpack/util/cache/download_cache_spec.rb index c082596df5..b482e8834b 100644 --- a/spec/java_buildpack/util/cache/download_cache_spec.rb +++ b/spec/java_buildpack/util/cache/download_cache_spec.rb @@ -326,18 +326,7 @@ .to_return(status: 200, body: 'foo-cached', headers: { Etag: 'foo-etag', 'Last-Modified' => 'foo-last-modified' }) allow(Net::HTTP).to receive(:Proxy).and_call_original - - # behavior changed between ruby 2 & 3 with how default hash kwargs are passed - # this causes different arguments for the mock based on the ruby version - # Remove this when we drop support for ruby 2 - case RUBY_VERSION - when /2\.\d+\.\d+/ - allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original - when /3\.\d+\.\d+/ - allow(Net::HTTP).to receive(:start).with('foo-uri', 80).and_call_original - else - raise 'unexpected ruby version' - end + allow(Net::HTTP).to receive(:start).with('foo-uri', 80).and_call_original download_cache.get(uri) {} end @@ -348,18 +337,7 @@ allow(ca_certs_directory).to receive(:exist?).and_return(true) allow(Net::HTTP).to receive(:Proxy).and_call_original - - # behavior changed between ruby 2 & 3 with how default hash kwargs are passed - # this causes different arguments for the mock based on the ruby version - # Remove this when we drop support for ruby 2 - case RUBY_VERSION - when /2\.\d+\.\d+/ - allow(Net::HTTP).to receive(:start).with('foo-uri', 80, {}).and_call_original - when /3\.\d+\.\d+/ - allow(Net::HTTP).to receive(:start).with('foo-uri', 80).and_call_original - else - raise 'unexpected ruby version' - end + allow(Net::HTTP).to receive(:start).with('foo-uri', 80).and_call_original download_cache.get(uri) {} end diff --git a/spec/java_buildpack/util/filtering_pathname_spec.rb b/spec/java_buildpack/util/filtering_pathname_spec.rb index 730cf66be6..0fdf972073 100644 --- a/spec/java_buildpack/util/filtering_pathname_spec.rb +++ b/spec/java_buildpack/util/filtering_pathname_spec.rb @@ -409,15 +409,15 @@ end it 'raises error if getwd is used' do - expect { described_class.getwd }.to raise_error(/undefined method `getwd'/) + expect { described_class.getwd }.to raise_error(NoMethodError, /undefined method [`']getwd'/) end it 'raises error if glob is used' do - expect { described_class.glob '' }.to raise_error(/undefined method `glob'/) + expect { described_class.glob '' }.to raise_error(NoMethodError, /undefined method [`']glob'/) end it 'raises error if pwd is used' do - expect { described_class.pwd }.to raise_error(/undefined method `pwd'/) + expect { described_class.pwd }.to raise_error(NoMethodError, /undefined method [`']pwd'/) end def create_file(filename) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c6b0021bf5..6012db5df9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,6 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +require 'tmpdir' require 'webmock/rspec' WebMock.disable_net_connect!(allow: 'codeclimate.com') From c269b5f37300e76028d4b4531c8f4ff0fbf81661 Mon Sep 17 00:00:00 2001 From: ramonskie Date: Tue, 18 Nov 2025 11:01:07 +0100 Subject: [PATCH 807/812] Update RuboCop toolchain for Ruby 3.4 support Add racc gem required by RuboCop parser in Ruby 3.4+, and update RuboCop to version 1.60+ which recognizes Ruby 3.4 as a supported version. Key changes: - Add racc gem (required by parser gem in Ruby 3.4+) - Update rubocop from 1.28.2 to 1.81.7 (adds Ruby 3.4 support) - Update rubocop-rspec from 2.10.0 to 3.8.0 - Modernize .rubocop.yml configuration: - Change 'require' to 'plugins' (new preferred syntax) - Replace deprecated RSpec/FilePath with RSpec/SpecFilePathFormat and RSpec/SpecFilePathSuffix - Update RSpec/VerifiedDoubleReference config (obsolete EnforcedStyle) This allows the buildpack's code quality tools to work with Ruby 3.4.7. --- .rubocop.yml | 4 ++-- Gemfile | 3 ++- Gemfile.lock | 47 +++++++++++++++++++++++++++++------------------ 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 49fe20c4f8..38f85fc115 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ --- -require: +plugins: - rubocop-rspec AllCops: @@ -67,7 +67,7 @@ Lint/EmptyBlock: RSpec/MultipleMemoizedHelpers: Max: 10 RSpec/VerifiedDoubleReference: - EnforcedStyle: string + Enabled: false Style/OptionalBooleanParameter: Enabled: false Lint/RedundantCopDisableDirective: diff --git a/Gemfile b/Gemfile index e0334918f5..9c057db63f 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,7 @@ source 'https://rubygems.org' gem 'base64' gem 'bigdecimal' gem 'digest' +gem 'racc' gem 'set' gem 'tmpdir' @@ -13,7 +14,7 @@ group :development do gem 'rake' gem 'redcarpet' gem 'rspec' - gem 'rubocop' + gem 'rubocop', '~> 1.60' gem 'rubocop-rspec' gem 'rubyzip' gem 'tee' diff --git a/Gemfile.lock b/Gemfile.lock index 3e3741456a..9206946216 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ GEM specs: addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) - ast (2.4.2) + ast (2.4.3) base64 (0.3.0) bigdecimal (3.3.1) crack (0.4.5) @@ -12,15 +12,21 @@ GEM digest (3.2.1) fileutils (1.8.0) hashdiff (1.0.1) - parallel (1.22.1) - parser (3.1.2.0) + json (2.16.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + parallel (1.27.0) + parser (3.3.10.0) ast (~> 2.4.1) + racc + prism (1.6.0) public_suffix (4.0.7) + racc (1.8.1) rainbow (3.1.1) rake (13.0.6) redcarpet (3.5.1) - regexp_parser (2.3.1) - rexml (3.2.5) + regexp_parser (2.11.3) + rexml (3.4.4) rspec (3.11.0) rspec-core (~> 3.11.0) rspec-expectations (~> 3.11.0) @@ -34,20 +40,24 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) rspec-support (3.11.0) - rubocop (1.28.2) + rubocop (1.81.7) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) parallel (~> 1.10) - parser (>= 3.1.0.0) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml - rubocop-ast (>= 1.17.0, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.17.0) - parser (>= 3.1.1.0) - rubocop-rspec (2.10.0) - rubocop (~> 1.19) - ruby-progressbar (1.11.0) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.48.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-rspec (3.8.0) + lint_roller (~> 1.1) + rubocop (~> 1.81) + ruby-progressbar (1.13.0) rubyzip (2.3.2) set (1.1.2) tee (1.0.0) @@ -55,7 +65,7 @@ GEM unicode-display_width (>= 1.1.1, < 3) tmpdir (0.3.1) fileutils - unicode-display_width (2.1.0) + unicode-display_width (2.6.0) webmock (3.14.0) addressable (>= 2.8.0) crack (>= 0.3.2) @@ -71,10 +81,11 @@ DEPENDENCIES base64 bigdecimal digest + racc rake redcarpet rspec - rubocop + rubocop (~> 1.60) rubocop-rspec rubyzip set From a3f1d4c684bd3928b3f5da18d7f7f101a9b5e9bf Mon Sep 17 00:00:00 2001 From: ramonskie Date: Tue, 18 Nov 2025 11:01:29 +0100 Subject: [PATCH 808/812] Fix JavaMemoryAssistant spec missing test helper Add missing sub_configuration_context helper method to java_memory_assistant_spec.rb. This test has been broken since it was originally added in commit f2eee850 (Oct 26, 2016). The test references sub_configuration_context() on line 59 but never defined the helper method. Other specs (tomcat_spec.rb, open_jdk_like_spec.rb, ibm_jre_spec.rb) each define their own local helper following the same pattern. This is a pre-existing bug unrelated to the Ruby 3.4 migration - the test would have failed on any Ruby version (2.5, 2.6, 2.7, 3.0, 3.1, 3.4) with NoMethodError for undefined method 'sub_configuration_context'. Fixes #436 (original PR where test was introduced) --- spec/java_buildpack/framework/java_memory_assistant_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/java_buildpack/framework/java_memory_assistant_spec.rb b/spec/java_buildpack/framework/java_memory_assistant_spec.rb index 6390202362..46ec183291 100644 --- a/spec/java_buildpack/framework/java_memory_assistant_spec.rb +++ b/spec/java_buildpack/framework/java_memory_assistant_spec.rb @@ -73,3 +73,9 @@ class StubJavaMemoryAssistant < JavaBuildpack::Framework::JavaMemoryAssistant public :command, :sub_components, :supports? end + +def sub_configuration_context(configuration) + c = context.clone + c[:configuration] = configuration + c +end From df40274d7464738f5bfaaf8c3aaa3da81a8339af Mon Sep 17 00:00:00 2001 From: ramonskie Date: Tue, 18 Nov 2025 11:19:12 +0100 Subject: [PATCH 809/812] Fix REXML compatibility issues for Ruby 3.4 - Update TomcatGeodeStore to properly create XML documents with REXML - Ruby 3.4's REXML no longer allows creating documents with just XML declaration - Remove trailing whitespace from XML fixture files (REXML Pretty formatter now strips these) - All 972 non-integration tests now passing --- lib/java_buildpack/container/tomcat/tomcat_geode_store.rb | 3 ++- .../container_no_tomcat_version_geode_store_context_after.xml | 2 +- spec/fixtures/container_tomcat_geode_store_context_after.xml | 2 +- spec/fixtures/container_tomcat_redis_store_context_after.xml | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb index 5973f26fe3..c3b8c69fd9 100644 --- a/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb +++ b/lib/java_buildpack/container/tomcat/tomcat_geode_store.rb @@ -129,7 +129,8 @@ def cache_client_xml_path end def create_cache_client_xml - document = REXML::Document.new('') + document = REXML::Document.new + document << REXML::XMLDecl.new('1.0', 'UTF-8') add_client_cache document write_xml cache_client_xml_path, document end diff --git a/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml b/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml index 4dac5ae1c8..6eec7d93fe 100644 --- a/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml +++ b/spec/fixtures/container_no_tomcat_version_geode_store_context_after.xml @@ -14,7 +14,7 @@ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. - --> + --> diff --git a/spec/fixtures/container_tomcat_geode_store_context_after.xml b/spec/fixtures/container_tomcat_geode_store_context_after.xml index 8eb45842b4..5eb5387deb 100644 --- a/spec/fixtures/container_tomcat_geode_store_context_after.xml +++ b/spec/fixtures/container_tomcat_geode_store_context_after.xml @@ -14,7 +14,7 @@ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. - --> + --> diff --git a/spec/fixtures/container_tomcat_redis_store_context_after.xml b/spec/fixtures/container_tomcat_redis_store_context_after.xml index 6fdfc7bf0a..d762cf8cfb 100644 --- a/spec/fixtures/container_tomcat_redis_store_context_after.xml +++ b/spec/fixtures/container_tomcat_redis_store_context_after.xml @@ -14,7 +14,7 @@ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. - --> + --> From 8d7800bd6d40f752f2d38eb6547032a0fa9b4d86 Mon Sep 17 00:00:00 2001 From: ramonskie Date: Tue, 18 Nov 2025 11:53:03 +0100 Subject: [PATCH 810/812] Update platform support from bionic to jammy/noble - Remove bionic (Ubuntu 18.04 EOL April 2023) from PLATFORMS - Add noble (Ubuntu 24.04 LTS) to PLATFORMS for future support - Keep jammy (Ubuntu 22.04 LTS) as primary supported platform - Update all documentation references from bionic to jammy - Aligns buildpack with Ubuntu LTS lifecycle and support dates The platform detection at runtime already supported all Ubuntu codenames via /etc/os-release parsing. This change only affects offline buildpack packaging (which platforms to cache) and documentation examples. --- docs/extending-repositories.md | 4 ++-- docs/framework-google_stackdriver_debugger.md | 2 +- docs/framework-google_stackdriver_profiler.md | 2 +- docs/framework-your_kit_profiler.md | 4 ++-- docs/jre-graal_vm_jre.md | 4 ++-- docs/jre-open_jdk_jre.md | 8 ++++---- docs/jre-oracle_jre.md | 4 ++-- docs/jre-sap_machine_jre.md | 8 ++++---- docs/jre-zing_jre.md | 4 ++-- docs/jre-zulu_jre.md | 4 ++-- rakelib/package.rb | 2 +- 11 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/extending-repositories.md b/docs/extending-repositories.md index f1c58a6ac1..9d7854f17d 100644 --- a/docs/extending-repositories.md +++ b/docs/extending-repositories.md @@ -55,7 +55,7 @@ end | Variable | Description | | -------- | ----------- | | `{default.repository.root}` | The common root for all repositories. Currently defaults to `https://java-buildpack.cloudfoundry.org`. -| `{platform}` | The platform that the application is running on. Currently detects `bionic`. +| `{platform}` | The platform that the application is running on. Currently detects `jammy`, `noble`, etc. | `{architecture}` | The architecture of the system as returned by Ruby. The value is typically one of `x86_64` or `x86`. ## Configuration @@ -95,5 +95,5 @@ In addition to declaring a specific versions to use, you can also specify a boun [`config/repository.yml`]: ../config/repository.yml [`JavaBuildpack::Repository::ConfiguredItem`]: ../lib/java_buildpack/repository/configured_item.rb [Configuration and Extension]: ../README.md#configuration-and-extension -[example]: https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/index.yml +[example]: https://java-buildpack.cloudfoundry.org/openjdk/jammy/x86_64/index.yml diff --git a/docs/framework-google_stackdriver_debugger.md b/docs/framework-google_stackdriver_debugger.md index adf4bca22a..82d1a4b991 100644 --- a/docs/framework-google_stackdriver_debugger.md +++ b/docs/framework-google_stackdriver_debugger.md @@ -39,5 +39,5 @@ The framework can be configured by modifying the [`config/google_stackdriver_deb [`config/google_stackdriver_debugger.yml`]: ../config/google_stackdriver_debugger.yml [Google Stackdriver Debugger Service]: https://cloud.google.com/debugger/ [repositories]: extending-repositories.md -[this listing]: https://java-buildpack.cloudfoundry.org/google-stackdriver-debugger/bionic/x86_64/index.yml +[this listing]: https://java-buildpack.cloudfoundry.org/google-stackdriver-debugger/jammy/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/framework-google_stackdriver_profiler.md b/docs/framework-google_stackdriver_profiler.md index bbc174efaa..7bc3fa645f 100644 --- a/docs/framework-google_stackdriver_profiler.md +++ b/docs/framework-google_stackdriver_profiler.md @@ -39,5 +39,5 @@ The framework can be configured by modifying the [`config/google_stackdriver_pro [`config/google_stackdriver_profiler.yml`]: ../config/google_stackdriver_profiler.yml [Google Stackdriver Profiler Service]: https://cloud.google.com/profiler/ [repositories]: extending-repositories.md -[this listing]: https://java-buildpack.cloudfoundry.org/google-stackdriver-profiler/bionic/x86_64/index.yml +[this listing]: https://java-buildpack.cloudfoundry.org/google-stackdriver-profiler/jammy/x86_64/index.yml [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/framework-your_kit_profiler.md b/docs/framework-your_kit_profiler.md index 45d98685a2..8c56095116 100644 --- a/docs/framework-your_kit_profiler.md +++ b/docs/framework-your_kit_profiler.md @@ -24,7 +24,7 @@ The framework can be configured by creating or modifying the [`config/your_kit_p | `enabled` | Whether to enable the YourKit Profiler | `port` | The port that the YourKit Profiler will listen on. Defaults to `10001`. | `repository_root` | The URL of the YourKit Profiler repository index ([details][repositories]). -| `version` | The version of the YourKit Profiler to use. Candidate versions can be found in the listings for [bionic][]. +| `version` | The version of the YourKit Profiler to use. Candidate versions can be found in the listings for [jammy][]. ## Creating SSH Tunnel After starting an application with the YourKit Profiler enabled, an SSH tunnel must be created to the container. To create that SSH container, execute the following command: @@ -40,7 +40,7 @@ Once the SSH tunnel has been created, your YourKit Profiler should connect to `l ![YourKit Configuration](framework-your_kit_profiler.png) [`config/your_kit_profiler.yml`]: ../config/your_kit_profiler.yml -[bionic]: https://download.run.pivotal.io/your-kit/bioni/x86_64/index.yml +[jammy]: https://download.run.pivotal.io/your-kit/bioni/x86_64/index.yml [Configuration and Extension]: ../README.md#configuration-and-extension [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/jre-graal_vm_jre.md b/docs/jre-graal_vm_jre.md index c80ef30372..5ec9a60144 100644 --- a/docs/jre-graal_vm_jre.md +++ b/docs/jre-graal_vm_jre.md @@ -44,7 +44,7 @@ cf restage | `jre.repository_root` | The URL of the GraalVM repository index ([details][repositories]). | `jre.version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [jammy][jvmkill-jammy]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -169,7 +169,7 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [`config/graal_vm_jre.yml`]: ../config/graal_vm_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml +[jvmkill-jammy]: https://java-buildpack.cloudfoundry.org/jvmkill/jammy/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [OpenJDK JRE]: jre-open_jdk_jre.md [GraalVM]: https://www.graalvm.org/ diff --git a/docs/jre-open_jdk_jre.md b/docs/jre-open_jdk_jre.md index 050de39b28..f5cac3083e 100644 --- a/docs/jre-open_jdk_jre.md +++ b/docs/jre-open_jdk_jre.md @@ -25,9 +25,9 @@ The JRE can be configured by modifying the [`config/open_jdk_jre.yml`][] file in | Name | Description | ---- | ----------- | `jre.repository_root` | The URL of the OpenJDK repository index ([details][repositories]). -| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [bionic][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [jammy][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [jammy][jvmkill-jammy]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -152,10 +152,10 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 ``` [`config/open_jdk_jre.yml`]: ../config/open_jdk_jre.yml -[bionic]: https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/index.yml +[jammy]: https://java-buildpack.cloudfoundry.org/openjdk/jammy/x86_64/index.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml +[jvmkill-jammy]: https://java-buildpack.cloudfoundry.org/jvmkill/jammy/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [OpenJDK]: http://openjdk.java.net [repositories]: extending-repositories.md diff --git a/docs/jre-oracle_jre.md b/docs/jre-oracle_jre.md index 48d1091ae5..2b0635d3d0 100644 --- a/docs/jre-oracle_jre.md +++ b/docs/jre-oracle_jre.md @@ -44,7 +44,7 @@ cf restage | `jre.repository_root` | The URL of the Oracle repository index ([details][repositories]). | `jre.version` | The version of Java runtime to use. Candidate versions can be found in the the repository that you have created to house the JREs. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [jammy][jvmkill-jammy]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -172,7 +172,7 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [`config/oracle_jre.yml`]: ../config/oracle_jre.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml +[jvmkill-jammy]: https://java-buildpack.cloudfoundry.org/jvmkill/jammy/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [OpenJDK JRE]: jre-open_jdk_jre.md [Oracle]: http://www.oracle.com/technetwork/java/index.html diff --git a/docs/jre-sap_machine_jre.md b/docs/jre-sap_machine_jre.md index 28057bb20d..2aee4e2fb3 100644 --- a/docs/jre-sap_machine_jre.md +++ b/docs/jre-sap_machine_jre.md @@ -32,9 +32,9 @@ cf restage | Name | Description | ---- | ----------- | `jre.repository_root` | The URL of the SapMachine repository index ([details][repositories]). -| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [bionic][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. +| `jre.version` | The version of Java runtime to use. Candidate versions can be found in the listings for [jammy][]. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [jammy][jvmkill-jammy]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -155,10 +155,10 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 ``` [`config/sap_machine_jre.yml`]: ../config/sap_machine_jre.yml -[bionic]: https://java-buildpack.cloudfoundry.org/openjdk/bionic/x86_64/index.yml +[jammy]: https://java-buildpack.cloudfoundry.org/openjdk/jammy/x86_64/index.yml [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml +[jvmkill-jammy]: https://java-buildpack.cloudfoundry.org/jvmkill/jammy/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [repositories]: extending-repositories.md [SapMachine]: https://sapmachine.io diff --git a/docs/jre-zing_jre.md b/docs/jre-zing_jre.md index 8e4b097317..c29adb9595 100644 --- a/docs/jre-zing_jre.md +++ b/docs/jre-zing_jre.md @@ -36,7 +36,7 @@ cf restage | `jre.repository_root` | The URL of the Azul Platform Prime repository index ([details][repositories]). | `jre.version` | The version of Java runtime to use. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [jammy][jvmkill-jammy]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -138,7 +138,7 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [Azul Platform Prime]: https://www.azul.com/products/prime/ [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml +[jvmkill-jammy]: https://java-buildpack.cloudfoundry.org/jvmkill/jammy/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/docs/jre-zulu_jre.md b/docs/jre-zulu_jre.md index cc70bec43b..8d5bbb5bdd 100644 --- a/docs/jre-zulu_jre.md +++ b/docs/jre-zulu_jre.md @@ -35,7 +35,7 @@ cf restage | `jre.repository_root` | The URL of the Zulu repository index ([details][repositories]). | `jre.version` | The version of Java runtime to use. Note: version 1.8.0 and higher require the `memory_sizes` and `memory_heuristics` mappings to specify `metaspace` rather than `permgen`. | `jvmkill.repository_root` | The URL of the `jvmkill` repository index ([details][repositories]). -| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [bionic][jvmkill-bionic]. +| `jvmkill.version` | The version of `jvmkill` to use. Candidate versions can be found in the listings for [jammy][jvmkill-jammy]. | `memory_calculator` | Memory calculator defaults, described below under "Memory". ### Additional Resources @@ -164,7 +164,7 @@ JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=99199 [Azul Zulu]: https://www.azul.com/products/zulu/ [Configuration and Extension]: ../README.md#configuration-and-extension [Java Buildpack Memory Calculator]: https://github.com/cloudfoundry/java-buildpack-memory-calculator -[jvmkill-bionic]: https://java-buildpack.cloudfoundry.org/jvmkill/bionic/x86_64/index.yml +[jvmkill-jammy]: https://java-buildpack.cloudfoundry.org/jvmkill/jammy/x86_64/index.yml [Memory Calculator's README]: https://github.com/cloudfoundry/java-buildpack-memory-calculator [repositories]: extending-repositories.md [version syntax]: extending-repositories.md#version-syntax-and-ordering diff --git a/rakelib/package.rb b/rakelib/package.rb index f3948ee189..3635f27d55 100644 --- a/rakelib/package.rb +++ b/rakelib/package.rb @@ -76,7 +76,7 @@ def self.version BUILDPACK_VERSION = JavaBuildpack::BuildpackVersion.new(false).freeze - PLATFORMS = %w[bionic jammy].freeze + PLATFORMS = %w[jammy noble].freeze STAGING_DIR = "#{BUILD_DIR}/staging".freeze From 1e2bbbcc1d0bf8802b33bb6d0c201275f3b561fc Mon Sep 17 00:00:00 2001 From: ramonskie Date: Tue, 18 Nov 2025 11:57:35 +0100 Subject: [PATCH 811/812] Update CI Dockerfile to Ruby 3.4.7 and Ubuntu Jammy - Update base image from ubuntu:bionic to ubuntu:jammy - Remove old Ruby versions (2.5.9, 2.7.6, 3.0.4, 3.1.3) - Install only Ruby 3.4.7 and set as global default - Update libssl1.0-dev to libssl-dev for jammy compatibility - Update python to python3 (Python 2 removed from jammy) - Align bundler version with Gemfile.lock (2.3.12) This streamlines CI builds and aligns with the Ruby 3.4.7 migration. Reduces Docker image build time and size by removing 3 unused Ruby versions. --- ci/Dockerfile | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/ci/Dockerfile b/ci/Dockerfile index 79a666b0c0..0b9bc77e52 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,4 +1,4 @@ -ARG base_image=ubuntu:bionic +ARG base_image=ubuntu:jammy FROM ${base_image} RUN apt-get update && apt-get install -y wget gnupg @@ -10,11 +10,13 @@ RUN apt-get update && apt-get install -y \ build-essential \ curl \ git \ - libssl1.0-dev \ + libffi-dev \ + libssl-dev \ libreadline-dev \ + libyaml-dev \ lsb-release \ locales \ - python \ + python3 \ zip \ zlib1g-dev \ bellsoft-java17 \ @@ -32,16 +34,8 @@ RUN eval "$(rbenv init -)" \ RUN eval "$(rbenv init -)" \ && git clone https://github.com/sstephenson/rbenv-default-gems.git $(rbenv root)/plugins/rbenv-default-gems \ - && echo 'bundler 2.3.26' >> $(rbenv root)/default-gems + && echo 'bundler 2.3.12' >> $(rbenv root)/default-gems RUN eval "$(rbenv init -)" \ - && rbenv install 2.5.9 - -RUN eval "$(rbenv init -)" \ - && rbenv install 2.7.6 - -RUN eval "$(rbenv init -)" \ - && rbenv install 3.0.4 - -RUN eval "$(rbenv init -)" \ - && rbenv install 3.1.3 + && rbenv install 3.4.7 \ + && rbenv global 3.4.7 From a17ea51d480cf82a983d844de50afcc5e2de2afe Mon Sep 17 00:00:00 2001 From: ramonskie Date: Mon, 24 Nov 2025 16:28:21 +0100 Subject: [PATCH 812/812] Fix Ruby version compatibility by always using buildpack Ruby instead of system Ruby --- bin/run | 8 +++++--- config/ruby.yml | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bin/run b/bin/run index dc6220f0f1..f7ea7c9633 100755 --- a/bin/run +++ b/bin/run @@ -93,13 +93,15 @@ function main() { local phase phase="$(basename "${0}")" - if ! which ruby > /dev/null; then - mkdir -p "${RUBY_DIR}" + # Always install and use buildpack Ruby to ensure consistent version + # regardless of system Ruby availability + mkdir -p "${RUBY_DIR}" + if [ ! -d "${RUBY_DIR}/bin" ]; then util::install - util::environment::setup fi + util::environment::setup exec "${BUILDPACK_DIR}/bin/ruby-run" "${phase}" "${@-}" } diff --git a/config/ruby.yml b/config/ruby.yml index 94541f7ee4..0d05199092 100644 --- a/config/ruby.yml +++ b/config/ruby.yml @@ -14,6 +14,8 @@ # limitations under the License. # Configuration for Ruby +# Note: Ruby 3.2.8+ is required for Psych 5.0.1+ which supports YAML.load_file +# with permitted_classes and aliases keyword arguments used throughout the buildpack --- version: 3.2.+ repository_root: https://raw.githubusercontent.com/cloudfoundry/ruby-buildpack/master/java-index