Skip to content

Commit e06e00b

Browse files
committed
Merge branch '753-appdynamics-configuration'
Signed-off-by: Ben Hale <[email protected]>
2 parents 349e93b + f4cac21 commit e06e00b

File tree

2 files changed

+86
-7
lines changed

2 files changed

+86
-7
lines changed

lib/java_buildpack/framework/app_dynamics_agent.rb

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,28 @@ module Framework
2525
# Encapsulates the functionality for enabling zero-touch AppDynamics support.
2626
class AppDynamicsAgent < JavaBuildpack::Component::VersionedDependencyComponent
2727

28+
def initialize(context)
29+
super(context)
30+
@logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger AppDynamicsAgent
31+
end
32+
2833
# (see JavaBuildpack::Component::BaseComponent#compile)
2934
def compile
3035
download_zip(false, @droplet.sandbox, 'AppDynamics Agent')
3136

3237
# acessor for resources dir through @droplet?
33-
resources_dir = Pathname.new(File.expand_path('../../../resources', __dir__)).freeze
38+
resources_dir = Pathname.new(File.expand_path('../../../resources', __dir__)).freeze
3439
default_conf_dir = resources_dir + @droplet.component_id + 'defaults'
3540

3641
copy_appd_default_configuration(default_conf_dir)
37-
42+
override_default_config_if_applicable
3843
@droplet.copy_resources
3944
end
4045

4146
# (see JavaBuildpack::Component::BaseComponent#release)
4247
def release
4348
credentials = @application.services.find_service(FILTER, 'host-name')['credentials']
44-
java_opts = @droplet.java_opts
49+
java_opts = @droplet.java_opts
4550
java_opts.add_javaagent(@droplet.sandbox + 'javaagent.jar')
4651

4752
application_name java_opts, credentials
@@ -64,9 +69,12 @@ def supports?
6469

6570
private
6671

72+
CONFIG_FILES = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml
73+
service-endpoint.xml transactions.xml].freeze
74+
6775
FILTER = /app[-]?dynamics/.freeze
6876

69-
private_constant :FILTER
77+
private_constant :CONFIG_FILES, :FILTER
7078

7179
def application_name(java_opts, credentials)
7280
name = credentials['application-name'] || @configuration['default_application_name'] ||
@@ -129,7 +137,57 @@ def copy_appd_default_configuration(default_conf_dir)
129137
end
130138
end
131139

132-
end
140+
# Check if configuration file exists on the server before download
141+
# @param [ResourceURI] uri URI of the remote configuration server
142+
# @param [ConfigFileName] conf_file Name of the configuration file
143+
# @return [Boolean] returns true if files exists on path specified by APPD_CONF_HTTP_URL, false otherwise
144+
def check_if_resource_exists(resource_uri, conf_file)
145+
# check if resource exists on remote server
146+
begin
147+
response = Net::HTTP.start(resource_uri.host, resource_uri.port) do |http|
148+
http.request_head(resource_uri)
149+
end
150+
rescue StandardError => e
151+
@logger.error { "Request failure: #{e.message}" }
152+
return false
153+
end
133154

155+
case response
156+
when Net::HTTPSuccess
157+
return true
158+
when Net::HTTPRedirection
159+
location = response['location']
160+
@logger.info { "redirected to #{location}" }
161+
return check_if_resource_exists(location, conf_file)
162+
else
163+
@logger.info { "Could not retrieve #{resource_uri}. Code: #{response.code} Message: #{response.message}" }
164+
return false
165+
end
166+
end
167+
168+
# Check for configuration files on a remote server. If found, copy to conf dir under each ver* dir
169+
# @return [Void]
170+
def override_default_config_if_applicable
171+
return unless @application.environment['APPD_CONF_HTTP_URL']
172+
173+
agent_root = @application.environment['APPD_CONF_HTTP_URL'].chomp('/') + '/java/'
174+
@logger.info { "Downloading override configuration files from #{agent_root}" }
175+
CONFIG_FILES.each do |conf_file|
176+
uri = URI(agent_root + conf_file)
177+
178+
# `download()` uses retries with exponential backoff which is expensive
179+
# for situations like 404 File not Found. Also, `download()` doesn't expose
180+
# an api to disable retries, which makes this check necessary to prevent
181+
# long install times.
182+
next unless check_if_resource_exists(uri, conf_file)
183+
184+
download(false, uri.to_s) do |file|
185+
Dir.glob(@droplet.sandbox + 'ver*') do |target_directory|
186+
FileUtils.cp_r file, target_directory + '/conf/' + conf_file
187+
end
188+
end
189+
end
190+
end
191+
end
134192
end
135193
end

spec/java_buildpack/framework/app_dynamics_agent_spec.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,29 @@
141141
expect(java_opts).to include('-Dappdynamics.agent.accountAccessKey=test-account-access-key')
142142
end
143143
end
144-
end
145144

146-
end
145+
context do
146+
147+
let(:environment) { { 'APPD_CONF_HTTP_URL' => 'http://foo.com' } }
148+
let(:conf_files) { described_class.instance_variable_get(:@conf_files) }
149+
150+
it 'sets APPD_CONF_HTTP_URL env var to download config files from',
151+
cache_fixture: 'stub-app-dynamics-agent.zip' do
147152

153+
config_files = %w[logging/log4j2.xml logging/log4j.xml app-agent-config.xml controller-info.xml
154+
service-endpoint.xml transactions.xml]
155+
156+
config_files.each do |file|
157+
uri = "http://foo.com/java/#{file}"
158+
allow(application_cache).to receive(:get)
159+
.with(uri)
160+
stub_request(:head, uri)
161+
.with(headers: { 'Accept' => '*/*', 'Host' => 'foo.com', 'User-Agent' => 'Ruby' })
162+
.to_return(status: 200, body: '', headers: {})
163+
end
164+
component.compile
165+
end
166+
end
167+
end
168+
end
148169
end

0 commit comments

Comments
 (0)