Class: Contrast::Agent::Reporting::ReporterClient

Inherits:
Utils::NetHttpBase show all
Includes:
Endpoints, ReporterClientUtils, ResponseHandlerUtils, Components::Logger::InstanceMethods
Defined in:
lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb

Overview

This class creates a Net::HTTP client and initiates a connection to the provided result

Constant Summary collapse

RECORDABLE_EVENTS =

Returns events that may result in configuration changes.

Returns:

  • (Array<Class>)

    events that may result in configuration changes

[
  Contrast::Agent::Reporting::ServerSettings,
  Contrast::Agent::Reporting::ApplicationSettings,
  Contrast::Agent::Reporting::AgentStartup,
  Contrast::Agent::Reporting::ApplicationStartup
].cs__freeze
SERVICE_NAME =
'Reporter'
REPORT_CONFIG_WHEN =
%w[200 304].cs__freeze

Constants included from ResponseHandlerUtils

Contrast::Agent::Reporting::ResponseHandlerUtils::ANALYZE_WHEN, Contrast::Agent::Reporting::ResponseHandlerUtils::APP_NON_EXISTENT_MSG, Contrast::Agent::Reporting::ResponseHandlerUtils::ERROR_CODES, Contrast::Agent::Reporting::ResponseHandlerUtils::FORBIDDEN_MSG, Contrast::Agent::Reporting::ResponseHandlerUtils::FORBIDDEN_NO_ACTION_MSG, Contrast::Agent::Reporting::ResponseHandlerUtils::RETRY_AFTER_MSG, Contrast::Agent::Reporting::ResponseHandlerUtils::SUSPEND_MSG, Contrast::Agent::Reporting::ResponseHandlerUtils::UNPROCESSABLE_ENTITY_MSG, Contrast::Agent::Reporting::ResponseHandlerUtils::UNSUCCESSFULLY_RECEIVED_MSG

Constants included from ReporterClientUtils

Contrast::Agent::Reporting::ReporterClientUtils::STARTUP_EVENTS, Contrast::Agent::Reporting::ReporterClientUtils::STRING_ENCODING

Constants included from Endpoints

Endpoints::APP_LANGUAGE, Endpoints::ENDPOINT_VERSION, Endpoints::NG_ENDPOINTS

Constants included from Resend

Contrast::Agent::Reporting::Resend::END_RESENDING_MESSAGE, Contrast::Agent::Reporting::Resend::RESCUE_ATTEMPTS, Contrast::Agent::Reporting::Resend::RESENDING_MESSAGE, Contrast::Agent::Reporting::Resend::RETRY_ERRORS, Contrast::Agent::Reporting::Resend::TIMEOUT

Instance Attribute Summary collapse

Attributes inherited from Utils::NetHttpBase

#client_name

Instance Method Summary collapse

Methods included from Components::Logger::InstanceMethods

#cef_logger, #logger

Methods included from ResponseHandlerUtils

#last_application_modified, #last_response_code, #last_server_modified, #stop_reporting

Methods included from ReporterClientUtils

#audit

Methods included from Endpoints

application_activity, application_inventory, application_settings, application_startup, effective_config, heartbeat, library_usage, observed_route, server_settings, trace_observed

Methods included from Components::Scope::InstanceMethods

#contrast_enter_method_scopes!, #contrast_exit_method_scopes!, #with_app_scope, #with_contrast_scope, #with_deserialization_scope, #with_split_scope

Methods included from Resend

#disable_reporting, #end_of_rescue, #handle_resend, #handle_response_error, #try_resend

Methods inherited from Utils::NetHttpBase

#connection_verified?, last_error, last_error=

Constructor Details

#initializeReporterClient

Returns a new instance of ReporterClient.



42
43
44
45
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 42

def initialize
  @headers = Contrast::Agent::Reporting::Headers.new
  super()
end

Instance Attribute Details

#headersContrast::Agent::Reporting::Headers (readonly)

Returns the current value of headers.

Returns:



24
25
26
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 24

def headers
  @headers
end

Instance Method Details

#compress_event(event, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY) ⇒ String

Compress data with Zlib

Parameters:

  • event (Contrast::Agent::Reporting::ReportingEvent)
  • level (Integer) (defaults to: Zlib::DEFAULT_COMPRESSION)

    compression level

  • strategy (Integer) (defaults to: Zlib::DEFAULT_STRATEGY)

    compression strategy

Returns:

  • (String)

    compressed data



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 130

def compress_event event, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY
  compressed_data = StringIO.new.set_encoding(STRING_ENCODING)
  gzip = Zlib::GzipWriter.new(compressed_data, level, strategy)
  gzip.write(event.event_json)
  gzip.close
  gzip = nil
  compressed_event = compressed_data.string.dup
  compressed_data.close
  compressed_data = nil
  compressed_event
ensure
  gzip&.close
  compressed_data&.close
  compressed_event
end

#decompress(compresed_data) ⇒ Object

Reads compressed data

Parameters:



149
150
151
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 149

def decompress compresed_data
  Zlib::GzipReader.wrap(StringIO.new(compresed_data), &:read)
end

#diagnosticsObject



120
121
122
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 120

def diagnostics
  @_diagnostics ||= Contrast::Config::Diagnostics::Monitor.new(Contrast::LOGGER.path)
end

#enter_run_modeObject



173
174
175
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 173

def enter_run_mode
  response_handler.enter_run_mode
end

#initialize_connectionNet::HTTP?

This method initializes the Net::HTTP client we’ll need. it will validate the connection and make the first request. If connection is valid and response is available then the open connection is returned.

Returns:

  • (Net::HTTP, nil)

    Return open connection or nil



52
53
54
55
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 52

def initialize_connection
  # for this client we would use proxy and custom certificate file if available
  super(SERVICE_NAME, Contrast::API.api_url, use_proxy: true, use_custom_cert: true)
end

#modeObject



169
170
171
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 169

def mode
  response_handler.mode
end

#put_to_sleepObject



161
162
163
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 161

def put_to_sleep
  response_handler.put_to_sleep
end

#report_configuration(response, event) ⇒ Object

Write effective config to file: If we are here the create and server messages are sent and the code received is 200 or 304. In case of 304 there will be no new settings and we can write current ones. This is done on every settings request.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 96

def report_configuration response, event
  return unless response

  diagnostics.config.determine_config_status(response_handler.last_response_code || response.code)
  return unless REPORT_CONFIG_WHEN.include?(response_handler.last_response_code || response.code)
  return unless RECORDABLE_EVENTS.include?(event&.cs__class)

  logger.info('[Reporter Diagnostics] last response code:', response_code: response_handler.last_response_code)
  diagnostics.write_to_file
  config_event = Contrast::Agent::Reporting::AgentEffectiveConfig.new(diagnostics)
  Contrast::Agent.reporter.send_event(config_event)
rescue StandardError => e
  #  Don't let this error bubble up and stop the agent reporting, with resending triggered.
  logger.error('[Reporter] Error while reporting configuration', error: e, event_type: event&.cs__class)
end

#response_handlerObject



116
117
118
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 116

def response_handler
  @_response_handler ||= Contrast::Agent::Reporting::ResponseHandler.new
end

#send_event(event, connection) ⇒ Object

Check event type and send it to appropriate TS endpoint

Parameters:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 73

def send_event event, connection
  return unless connection
  return unless event.valid?

  logger.debug('[Reporter] Preparing to send reporting event', event_class: event.cs__class)
  request = build_request(event)
  response = connection.request(request)
  audit.audit_event(event, response) if ::Contrast::API.request_audit_enable
  process_settings_response(response, event)
  process_preflight_response(event, response, connection)
  report_configuration(response, event)
  response
rescue StandardError => e
  handle_response_error(event, connection, e)
end

#sleep?Boolean

Forwarders #

Returns:

  • (Boolean)


157
158
159
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 157

def sleep?
  response_handler.sleep?
end

#startup!(connection) ⇒ Object

Start the client for first time and sent startup event

Parameters:

  • connection (Net::HTTP)

    open connection



60
61
62
63
64
65
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 60

def startup! connection
  return if status.startup_messages_sent?
  return unless connection

  send_agent_startup(connection)
end

#statusObject



112
113
114
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 112

def status
  @_status ||= Contrast::Agent::Reporting::ConnectionStatus.new
end

#timeoutObject



165
166
167
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 165

def timeout
  response_handler.timeout
end

#wake_upObject



177
178
179
# File 'lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb', line 177

def wake_up
  response_handler.wake_up
end