Skip to content

Commit

Permalink
Instana Agent Implementation
Browse files Browse the repository at this point in the history
Instana Agent Implementation containing necessary framework code and tests.
  • Loading branch information
saurabhrajguru committed Mar 12, 2024
1 parent 1ca7a11 commit 90b4303
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 0 deletions.
1 change: 1 addition & 0 deletions config/components.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ frameworks:
- "JavaBuildpack::Framework::TakipiAgent"
- "JavaBuildpack::Framework::JavaSecurity"
- "JavaBuildpack::Framework::JavaOpts"
- "JavaBuildpack::Framework::InstanaAgent"
35 changes: 35 additions & 0 deletions docs/framework-instana_agent.md
Original file line number Diff line number Diff line change
@@ -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

<table>
<tr>
<td><strong>Detection Criterion</strong></td><td>Existence of a single bound Instana service.
<ul>
<li>Existence of a Instana service is defined as the <a href="http://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES"><code>VCAP_SERVICES</code></a> payload containing a service who's name, label or tag has <code>instana</code> as a substring with at least `agentkey` and `endpointurl` set as credentials.</li>
</ul>
</td>
</tr>
<tr>
<td><strong>Tags</strong></td>
<td><tt>instana-agent=&lt;version&gt;</tt></td>
</tr>
</table>
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

88 changes: 88 additions & 0 deletions lib/java_buildpack/framework/instana_agent.rb
Original file line number Diff line number Diff line change
@@ -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
Empty file.
70 changes: 70 additions & 0 deletions spec/java_buildpack/framework/instana_agent_spec.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 90b4303

Please sign in to comment.