# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true cs__scoped_require 'contrast/components/interface' cs__scoped_require 'contrast/agent/worker_thread' module Contrast module Api module Communication # Top level gateway to messaging with speedracer class MessagingQueue < Contrast::Agent::WorkerThread include Contrast::Components::Interface access_component :analysis, :logging, :settings attr_reader :queue, :speedracer def initialize @queue = Queue.new @speedracer = Contrast::Api::Communication::Speedracer.new super end # Use this to bypass the messaging queue and leave response processing to the caller def send_event_immediately event send_event(event, true) end # Use this to add a message to the queue and process the response internally def send_event_eventually event logger.debug('Enqueued event for sending', event_type: event.cs__class) queue << event if event end def start_thread! speedracer.ensure_startup! return if running? @_thread = Contrast::Agent::Thread.new do loop do event = queue.pop begin logger.debug('Dequeued event for sending', event_type: event.cs__class) send_event(event) rescue StandardError => e logger.error('Could not send message to service from messaging queue thread.', e) end end end logger.debug('Started background sending thread.') end private # return_response is used to determine if we want to return the response to the caller or process it internally def send_event event, return_response = false preprocess_event(event) if return_response speedracer.return_response(event) else speedracer.process_internally(event) end end # For now this only handles appending assess tags # eventually we could break out preprocessors for every event type def preprocess_event event return unless event.is_a?(Contrast::Api::Dtm::Activity) # So set their tags event.finding_tags = Contrast::Utils::StringUtils.force_utf8(ASSESS.tags) # and see if they're even enabled event.findings.delete_if { |finding| ASSESS.rule_disabled?(finding.rule_id) } end end end end end