Skip to content

Commit

Permalink
Merge branch 'main' into lc/sc-245755/adding-option-omit-anonymous-co…
Browse files Browse the repository at this point in the history
…ntexts
  • Loading branch information
louis-launchdarkly committed Jun 26, 2024
2 parents c47e6e2 + 9f6c902 commit 49451db
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "8.4.2"
".": "8.5.0"
}
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

All notable changes to the LaunchDarkly Ruby SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).

## [8.5.0](https://github.com/launchdarkly/ruby-server-sdk/compare/8.4.2...8.5.0) (2024-06-10)


### Features

* Support to_h and to_json methods for LDContext ([#284](https://github.com/launchdarkly/ruby-server-sdk/issues/284)) ([d3c8d40](https://github.com/launchdarkly/ruby-server-sdk/commit/d3c8d409b631f559239e48fb93eb5e4f9181254f))


### Bug Fixes

* Increment flag & segment versions when reloading from file data source ([#285](https://github.com/launchdarkly/ruby-server-sdk/issues/285)) ([7d5b051](https://github.com/launchdarkly/ruby-server-sdk/commit/7d5b051ec1b1e8990a7fb3def5798f064acd5e04))
* Log warning if client init timeout is considered high ([#278](https://github.com/launchdarkly/ruby-server-sdk/issues/278)) ([61f4c7e](https://github.com/launchdarkly/ruby-server-sdk/commit/61f4c7e589e9d0da94e4f289e9c601aa36028c95))

## [8.4.2](https://github.com/launchdarkly/ruby-server-sdk/compare/8.4.1...8.4.2) (2024-05-03)


Expand Down
2 changes: 1 addition & 1 deletion PROVENANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ To verify SLSA provenance attestations, we recommend using [slsa-verifier](https
<!-- x-release-please-start-version -->
```
# Set the version of the SDK to verify
SDK_VERSION=8.4.2
SDK_VERSION=8.5.0
```
<!-- x-release-please-end -->

Expand Down
43 changes: 43 additions & 0 deletions lib/ldclient-rb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,49 @@ def [](key)
multi_kind? ? individual_context(key.to_s) : get_value(key)
end

#
# Convert the LDContext to a JSON string.
#
# @param args [Array]
# @return [String]
#
def to_json(*args)
JSON.generate(to_h, *args)
end

#
# Convert the LDContext to a hash. If the LDContext is invalid, the hash will contain an error key with the error
# message.
#
# @return [Hash]
#
def to_h
return {error: error} unless valid?
return hash_single_kind unless multi_kind?

hash = {kind: 'multi'}
@contexts.each do |context|
single_kind_hash = context.to_h
kind = single_kind_hash.delete(:kind)
hash[kind] = single_kind_hash
end

hash
end

protected def hash_single_kind
hash = attributes.nil? ? {} : attributes.clone

hash[:kind] = kind
hash[:key] = key

hash[:name] = name unless name.nil?
hash[:anonymous] = anonymous if anonymous
hash[:_meta] = {privateAttributes: private_attributes} unless private_attributes.empty?

hash
end

#
# Retrieve the value of any top level, addressable attribute.
#
Expand Down
16 changes: 14 additions & 2 deletions lib/ldclient-rb/impl/integrations/file_data_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def initialize(data_store, data_source_update_sink, logger, options={})
@poll_interval = options[:poll_interval] || 1
@initialized = Concurrent::AtomicBoolean.new(false)
@ready = Concurrent::Event.new

@version_lock = Mutex.new
@last_version = 1
end

def initialized?
Expand Down Expand Up @@ -93,14 +96,22 @@ def load_all
end

def load_file(path, all_data)
version = 1
@version_lock.synchronize {
version = @last_version
@last_version += 1
}

parsed = parse_content(IO.read(path))
(parsed[:flags] || {}).each do |key, flag|
flag[:version] = version
add_item(all_data, FEATURES, flag)
end
(parsed[:flagValues] || {}).each do |key, value|
add_item(all_data, FEATURES, make_flag_with_value(key.to_s, value))
add_item(all_data, FEATURES, make_flag_with_value(key.to_s, value, version))
end
(parsed[:segments] || {}).each do |key, segment|
segment[:version] = version
add_item(all_data, SEGMENTS, segment)
end
end
Expand Down Expand Up @@ -134,10 +145,11 @@ def add_item(all_data, kind, item)
items[key] = Model.deserialize(kind, item)
end

def make_flag_with_value(key, value)
def make_flag_with_value(key, value, version)
{
key: key,
on: true,
version: version,
fallthrough: { variation: 0 },
variations: [ value ],
}
Expand Down
10 changes: 10 additions & 0 deletions lib/ldclient-rb/reference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@ def hash
([error] + components).hash
end

#
# Convert the Reference to a JSON string.
#
# @param args [Array]
# @return [String]
#
def to_json(*args)
JSON.generate(@raw_path, *args)
end

#
# Performs unescaping of attribute reference path components:
#
Expand Down
2 changes: 1 addition & 1 deletion lib/ldclient-rb/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module LaunchDarkly
VERSION = "8.4.2" # x-release-please-version
VERSION = "8.5.0" # x-release-please-version
end
59 changes: 59 additions & 0 deletions spec/context_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "ldclient-rb/context"
require "json"

module LaunchDarkly
describe LDContext do
Expand Down Expand Up @@ -148,6 +149,64 @@ module LaunchDarkly
expect(org_first.fully_qualified_key).to eq("org:b-org-key:user:a-user-key")
end
end

describe "converts back to JSON format" do
it "single kind contexts" do
contextHash = {
key: "launchdarkly",
kind: "org",
address: {
street: "1999 Harrison St Suite 1100",
city: "Oakland",
state: "CA",
zip: "94612",
_meta: {
privateAttributes: ["city"],
},
},
}
context = subject.create(contextHash)
contextJson = context.to_json
backToHash = JSON.parse(contextJson, symbolize_names: true)

expect(backToHash).to eq(contextHash)
end

it "multi kind contexts" do
contextHash = {
kind: "multi",
"org": {
key: "launchdarkly",
address: {
street: "1999 Harrison St Suite 1100",
city: "Oakland",
state: "CA",
zip: "94612",
},
_meta: {
privateAttributes: ["address/city"],
},
},
"user": {
key: "user-key",
name: "Ruby",
anonymous: true,
},
}
context = subject.create(contextHash)
contextJson = context.to_json
backToHash = JSON.parse(contextJson, symbolize_names: true)

expect(backToHash).to eq(contextHash)
end

it "invalid context returns error" do
context = subject.create({ key: "", kind: "user", name: "testing" })
expect(context.valid?).to be false
expect(context.to_h).to eq({ error: "context key must not be empty" })
expect(context.to_json).to eq({ error: "context key must not be empty" }.to_json)
end
end
end

describe "context counts" do
Expand Down

0 comments on commit 49451db

Please sign in to comment.