From 4a54bf423a30b5e11b4ef0ebc14737b5bebd96c2 Mon Sep 17 00:00:00 2001 From: Saurabh Rajguru Date: Tue, 12 Mar 2024 17:17:10 +0530 Subject: [PATCH 1/2] Instana Agent Implementation Instana Agent Implementation containing necessary framework code and tests. --- config/components.yml | 1 + docs/framework-instana_agent.md | 35 ++++++++ lib/java_buildpack/framework/instana_agent.rb | 88 +++++++++++++++++++ spec/fixtures/stub-instana-agent.jar | 0 .../framework/instana_agent_spec.rb | 70 +++++++++++++++ 5 files changed, 194 insertions(+) create mode 100644 docs/framework-instana_agent.md create mode 100644 lib/java_buildpack/framework/instana_agent.rb create mode 100644 spec/fixtures/stub-instana-agent.jar create mode 100644 spec/java_buildpack/framework/instana_agent_spec.rb diff --git a/config/components.yml b/config/components.yml index 90a12ec28e..8cf0c26884 100644 --- a/config/components.yml +++ b/config/components.yml @@ -80,3 +80,4 @@ frameworks: - "JavaBuildpack::Framework::TakipiAgent" - "JavaBuildpack::Framework::JavaSecurity" - "JavaBuildpack::Framework::JavaOpts" + - "JavaBuildpack::Framework::InstanaAgent" diff --git a/docs/framework-instana_agent.md b/docs/framework-instana_agent.md new file mode 100644 index 0000000000..ad07bc8c79 --- /dev/null +++ b/docs/framework-instana_agent.md @@ -0,0 +1,35 @@ +# Instana Agent Framework +[IBM Instana](https://www.ibm.com/products/instana) is the only real-time full-stack observability solution: zero sample tracing + +The Instana Agent Framework causes an application to be automatically configured to work with a bound Instana instance + + + + + + + + + +
Detection CriterionExistence of a single bound Instana service. +
    +
  • Existence of a Instana service is defined as the VCAP_SERVICES payload containing a service who's name, label or tag has instana as a substring with at least `agentkey` and `endpointurl` set as credentials.
  • +
+
Tagsinstana-agent=<version>
+Tags are printed to standard output by the buildpack detect script + +## User-Provided Service +Users must provide their own Instana service. A user-provided Instana service must have a name or tag with `instana` in it so that the Instana Framework will automatically configure the application to work with the service. + +The credential payload of the service may contain the following entries: + +| Name | Description +| ---- | ----------- +| `agentkey` | The agent key is used to create a relationship between the monitoring agent and the environment that it belongs to. +| `endpointurl` | This environment variable is your serverless monitoring endpoint. Make sure that you use the correct value for your region that starts with https://serverless-. + +## 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 + diff --git a/lib/java_buildpack/framework/instana_agent.rb b/lib/java_buildpack/framework/instana_agent.rb new file mode 100644 index 0000000000..ba87ead680 --- /dev/null +++ b/lib/java_buildpack/framework/instana_agent.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2024 the original author 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 JavaBuildpack + module Framework + # Encapsulates the functionality for enabling Instana support. + class InstanaAgent < JavaBuildpack::Component::VersionedDependencyComponent + + # 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] + + @version, @uri = standalone_agent_download_url if supports? + @logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger InstanaAgent + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + download_jar + rescue StandardError => e + @logger.error('Instana Download failed :' + e.to_s) + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + @droplet.java_opts.add_javaagent(agent_path) + setup_variables + end + + # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?) + def supports? + @application.services.one_service? FILTER, AGENT_KEY, ENDPOINT_URL + end + + # Provides the Agent Path + def agent_path + @droplet.sandbox + jar_name + end + + # Provides the Credentials + def credentials + @application.services.find_service(FILTER, AGENT_KEY, ENDPOINT_URL)['credentials'] + end + + private + + FILTER = /instana/.freeze + AGENT_KEY = 'agentkey' + ENDPOINT_URL = 'endpointurl' + INSTANA_AGENT_KEY = 'INSTANA_AGENT_KEY' + INSTANA_ENDPOINT_URL = 'INSTANA_ENDPOINT_URL' + INSTANA_BASE_URL = 'artifact-public.instana.io/artifactory' + INSTANA_COLLECTOR_PATH = 'rel-generic-instana-virtual/com/instana/standalone-collector-jvm' + + def standalone_agent_download_url + download_uri = "https://_:#{credentials[AGENT_KEY]}@#{INSTANA_BASE_URL}/#{INSTANA_COLLECTOR_PATH}/%5BRELEASE%5D/standalone-collector-jvm-%5BRELEASE%5D.jar" + ['latest', download_uri] + end + + def setup_variables + environment_variables = @droplet.environment_variables + environment_variables + .add_environment_variable(INSTANA_AGENT_KEY, credentials[AGENT_KEY]) + .add_environment_variable(INSTANA_ENDPOINT_URL, credentials[ENDPOINT_URL]) + end + + end + end +end diff --git a/spec/fixtures/stub-instana-agent.jar b/spec/fixtures/stub-instana-agent.jar new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/java_buildpack/framework/instana_agent_spec.rb b/spec/java_buildpack/framework/instana_agent_spec.rb new file mode 100644 index 0000000000..002b1f79d4 --- /dev/null +++ b/spec/java_buildpack/framework/instana_agent_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2024 the original author 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/instana_agent' +require 'java_buildpack/util/tokenized_version' + +describe JavaBuildpack::Framework::InstanaAgent do + include_context 'with component help' + + it 'does not detect without instana service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?).with(/instana/, 'agentkey', 'endpointurl').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'agentkey' => 'test-akey', + 'endpointurl' => 'test-epurl' }) + + allow(application_cache).to receive(:get) + .with('https://_:test-akey@artifact-public.instana.io/artifactory/rel-generic-instana-virtual/com/instana/standalone-collector-jvm/%5BRELEASE%5D/standalone-collector-jvm-%5BRELEASE%5D.jar') + .and_yield(Pathname.new('spec/fixtures/stub-instana-agent.jar').open, false) + end + + it 'detects with instana service' do + expect(component.detect).to eq('instana-agent=latest') + end + + it 'downloads instana agent jar', + cache_fixture: 'stub-instana-agent.jar' do + + component.compile + expect(sandbox + 'instana_agent-latest.jar').to exist + end + + it 'sets Java Agent with Instana Agent' do + + component.release + + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/instana_agent/instana_agent-latest.jar') + end + + it 'updates environment variables' do + + component.release + + expect(environment_variables).to include('INSTANA_AGENT_KEY=test-akey') + expect(environment_variables).to include('INSTANA_ENDPOINT_URL=test-epurl') + end + + end + +end From 809159a8c19c65706a84ba50757eb569ce365764 Mon Sep 17 00:00:00 2001 From: Saurabh Rajguru Date: Wed, 13 Mar 2024 14:18:10 +0530 Subject: [PATCH 2/2] Update docs/framework-instana_agent.md Incorporated suggestions Co-authored-by: Felix Marx <97086574+FelixMarxIBM@users.noreply.github.com> --- docs/framework-instana_agent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework-instana_agent.md b/docs/framework-instana_agent.md index ad07bc8c79..f5253b67e5 100644 --- a/docs/framework-instana_agent.md +++ b/docs/framework-instana_agent.md @@ -7,7 +7,7 @@ The Instana Agent Framework causes an application to be automatically configured Detection CriterionExistence of a single bound Instana service.