Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 22 additions & 17 deletions lib/datadog/appsec/instrumentation/gateway.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
# frozen_string_literal: true

require_relative 'gateway/middleware'

module Datadog
module AppSec
# Instrumentation for AppSec
module Instrumentation
# Instrumentation gateway implementation
class Gateway
# Instrumentation gateway middleware
class Middleware
attr_reader :key, :block

def initialize(key, &block)
@key = key
@block = block
end

def call(stack, env)
@block.call(stack, env)
end
end

private_constant :Middleware

def initialize
@middlewares = Hash.new { |h, k| h[k] = [] }
@pushed_events = {}
end

# NOTE: Be careful with pushed names because every pushed event name
# is recorded in order to provide an ability to any subscriber
# to check wether an arbitrary event had happened.
#
# WARNING: If we start pushing generated names we should consider
# limiting the storage of pushed names.
def push(name, env, &block)
@pushed_events[name] = true

block ||= -> {}
middlewares_for_name = @middlewares[name]

middlewares_for_name = middlewares[name]

return [block.call, nil] if middlewares_for_name.empty?

Expand All @@ -42,15 +48,14 @@ def push(name, env, &block)
end

def watch(name, key, &block)
@middlewares[name] << Middleware.new(key, &block) unless @middlewares[name].any? { |m| m.key == key }
@middlewares[name] << Middleware.new(key, &block) unless middlewares[name].any? { |m| m.key == key }
end

def pushed?(name)
@pushed_events.key?(name)
end
private

attr_reader :middlewares
end

# NOTE: This left as-is and will be depricated soon.
def self.gateway
@gateway ||= Gateway.new # TODO: not thread safe
end
Expand Down
24 changes: 0 additions & 24 deletions lib/datadog/appsec/instrumentation/gateway/middleware.rb

This file was deleted.

15 changes: 12 additions & 3 deletions sig/datadog/appsec/instrumentation/gateway.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,26 @@ module Datadog
type final_call = ^() -> final_call_result
type stack = ::Proc

# TODO: this should be a struct
type stack_result = ::Array[nil | middleware_result | final_call_result]

class Middleware
attr_reader key: ::Symbol
attr_reader block: ::Proc

def initialize: (::Symbol key) { (stack next, Instrumentation::Gateway::Argument env) -> stack_result } -> void
def call: (stack next, Gateway::Argument? env) -> stack_result
end

@middlewares: ::Hash[::String, ::Array[Middleware]]

def initialize: () -> void

def push: (::String name, Gateway::Argument env) ?{ () -> final_call_result } -> stack_result

def watch: (::String name, ::Symbol key) { (stack next, Gateway::Argument env) -> stack_result } -> void

def pushed?: (::String name) -> bool
private

attr_reader middlewares: ::Hash[::String, ::Array[Middleware]]
end

self.@gateway: Gateway
Expand Down
15 changes: 0 additions & 15 deletions sig/datadog/appsec/instrumentation/gateway/middleware.rbs

This file was deleted.

17 changes: 1 addition & 16 deletions spec/datadog/appsec/instrumentation/gateway_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

RSpec.describe Datadog::AppSec::Instrumentation::Gateway do
subject(:gateway) { described_class.new }
let(:middlewares) { gateway.instance_variable_get(:@middlewares) }
let(:middlewares) { gateway.send(:middlewares) }

describe '#watch' do
it 'stores middleware' do
Expand Down Expand Up @@ -81,19 +81,4 @@
expect(env_2).to eq({ a: :b, c: :d })
end
end

describe '#pushed?' do
it { expect(gateway.pushed?('event.0')).to be(false) }

it 'returns true if event was pushed' do
expect { gateway.push('event.1', {}) }.to change { gateway.pushed?('event.1') }
.from(false).to(true)

expect { gateway.push('event.2', {}) }.to change { gateway.pushed?('event.2') }
.from(false).to(true)

expect { gateway.push('event.2', {}) }.not_to change { gateway.pushed?('event.2') }
.from(true)
end
end
end
Loading