-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: OpenFeature provider for GO Feature Flag (#1)
- Loading branch information
1 parent
908cea3
commit b911046
Showing
18 changed files
with
2,078 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# By default, SwiftLint uses a set of sensible default rules you can adjust: | ||
disabled_rules: # rule identifiers turned on by default to exclude from running | ||
- colon | ||
- comma | ||
- control_statement | ||
opt_in_rules: # some rules are turned off by default, so you need to opt-in | ||
- empty_count # find all the available rules by running: `swiftlint rules` | ||
|
||
# Alternatively, specify all rules explicitly by uncommenting this option: | ||
# only_rules: # delete `disabled_rules` & `opt_in_rules` if using this | ||
# - empty_parameters | ||
# - vertical_whitespace | ||
|
||
analyzer_rules: # rules run by `swiftlint analyze` | ||
- explicit_self | ||
|
||
# Case-sensitive paths to include during linting. Directory paths supplied on the | ||
# command line will be ignored. | ||
included: | ||
- Sources | ||
excluded: # case-sensitive paths to ignore during linting. Takes precedence over `included` | ||
- Carthage | ||
- Pods | ||
- Sources/ExcludedFolder | ||
- Sources/ExcludedFile.swift | ||
- Sources/*/ExcludedFile.swift # exclude files with a wildcard | ||
|
||
# If true, SwiftLint will not fail if no lintable files are found. | ||
allow_zero_lintable_files: false | ||
|
||
# If true, SwiftLint will treat all warnings as errors. | ||
strict: false | ||
|
||
# The path to a baseline file, which will be used to filter out detected violations. | ||
baseline: Baseline.json | ||
|
||
# The path to save detected violations to as a new baseline. | ||
write_baseline: Baseline.json | ||
|
||
# configurable rules can be customized from this configuration file | ||
# binary rules can set their severity level | ||
force_cast: warning # implicitly | ||
force_try: | ||
severity: warning # explicitly | ||
# rules that have both warning and error levels, can set just the warning level | ||
# implicitly | ||
line_length: 120 | ||
# they can set both implicitly with an array | ||
type_body_length: | ||
- 300 # warning | ||
- 400 # error | ||
# or they can set both explicitly | ||
file_length: | ||
warning: 500 | ||
error: 1200 | ||
# naming rules can set warnings/errors for min_length and max_length | ||
# additionally they can set excluded names | ||
type_name: | ||
min_length: 4 # only warning | ||
max_length: # warning and error | ||
warning: 40 | ||
error: 50 | ||
excluded: iPhone # excluded via string | ||
allowed_symbols: ["_"] # these are allowed in type names | ||
identifier_name: | ||
min_length: # only min_length | ||
error: 4 # only error | ||
excluded: # excluded via string array | ||
- id | ||
- URL | ||
- url | ||
- GlobalAPIKey | ||
- key | ||
- dto | ||
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging, summary) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"object": { | ||
"pins": [ | ||
{ | ||
"package": "OpenFeature", | ||
"repositoryURL": "https://github.com/open-feature/swift-sdk.git", | ||
"state": { | ||
"branch": null, | ||
"revision": "02b033c954766e86d5706bfc8ee5248244c11e77", | ||
"version": "0.1.0" | ||
} | ||
} | ||
] | ||
}, | ||
"version": 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// swift-tools-version: 5.5 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "go-feature-flag-provider", | ||
platforms: [ | ||
.iOS(.v14), | ||
.macOS(.v12) | ||
], | ||
products: [ | ||
.library( | ||
name: "go-feature-flag-provider", | ||
targets: ["go-feature-flag-provider"]) | ||
], | ||
dependencies: [ | ||
.package(url: "https://github.com/open-feature/swift-sdk.git", from: "0.1.0") | ||
], | ||
targets: [ | ||
.target( | ||
name: "go-feature-flag-provider", | ||
dependencies: [ | ||
.product(name: "OpenFeature", package: "swift-sdk") | ||
], | ||
plugins:[] | ||
), | ||
.testTarget( | ||
name: "go-feature-flag-providerTests", | ||
dependencies: [ | ||
"go-feature-flag-provider" | ||
] | ||
) | ||
] | ||
) |
79 changes: 79 additions & 0 deletions
79
Sources/go-feature-flag-provider/controller/ofrep_api.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import Foundation | ||
import OpenFeature | ||
|
||
class OfrepAPI { | ||
private let networkingService: NetworkingService | ||
private var etag: String = "" | ||
private let options: GoFeatureFlagProviderOptions | ||
|
||
init(networkingService: NetworkingService, options: GoFeatureFlagProviderOptions) { | ||
self.networkingService = networkingService | ||
self.options = options | ||
} | ||
|
||
func postBulkEvaluateFlags(context: EvaluationContext?) async throws -> (OfrepEvaluationResponse, HTTPURLResponse) { | ||
guard let context = context else { | ||
throw OpenFeatureError.invalidContextError | ||
} | ||
try validateContext(context: context) | ||
|
||
guard let url = URL(string: options.endpoint) else { | ||
throw InvalidOptions.invalidEndpoint(message: "endpoint [" + options.endpoint + "] is not valid") | ||
} | ||
let ofrepURL = url.appendingPathComponent("ofrep/v1/evaluate/flags") | ||
var request = URLRequest(url: ofrepURL) | ||
request.httpMethod = "POST" | ||
request.httpBody = try EvaluationRequest.convertEvaluationContext(context: context).asJSONData() | ||
request.setValue( | ||
"application/json", | ||
forHTTPHeaderField: "Content-Type" | ||
) | ||
|
||
if etag != "" { | ||
request.setValue(etag, forHTTPHeaderField: "If-None-Match") | ||
} | ||
|
||
let (data, response) = try await networkingService.doRequest(for: request) | ||
guard let httpResponse = response as? HTTPURLResponse else { | ||
throw OfrepError.httpResponseCastError | ||
} | ||
|
||
if httpResponse.statusCode == 401 { | ||
throw OfrepError.apiUnauthorizedError(response: httpResponse) | ||
} | ||
if httpResponse.statusCode == 403 { | ||
throw OfrepError.forbiddenError(response: httpResponse) | ||
} | ||
if httpResponse.statusCode == 429 { | ||
throw OfrepError.apiTooManyRequestsError(response: httpResponse) | ||
} | ||
if httpResponse.statusCode > 400 { | ||
throw OfrepError.unexpectedResponseError(response: httpResponse) | ||
} | ||
if httpResponse.statusCode == 304 { | ||
return (OfrepEvaluationResponse(flags: [], errorCode: nil, errorDetails: nil), httpResponse) | ||
} | ||
|
||
// Store ETag to use it in the next request | ||
if let etagHeaderValue = httpResponse.value(forHTTPHeaderField: "ETag") { | ||
if etagHeaderValue != "" && httpResponse.statusCode == 200 { | ||
etag = etagHeaderValue | ||
} | ||
} | ||
|
||
do { | ||
let dto = try JSONDecoder().decode(EvaluationResponseDTO.self, from: data) | ||
let evaluationResponse = OfrepEvaluationResponse.fromEvaluationResponseDTO(dto: dto) | ||
return (evaluationResponse, httpResponse) | ||
} catch { | ||
throw OfrepError.unmarshallError(error: error) | ||
} | ||
} | ||
|
||
private func validateContext(context: EvaluationContext) throws { | ||
let targetingKey = context.getTargetingKey() | ||
if targetingKey.isEmpty { | ||
throw OpenFeatureError.targetingKeyMissingError | ||
} | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
Sources/go-feature-flag-provider/exception/ofrep_exceptions.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by thomas.poignant on 27/06/2024. | ||
// | ||
|
||
import Foundation | ||
|
||
enum OfrepError: Error { | ||
case httpResponseCastError | ||
case unmarshallError(error: Error) | ||
case apiUnauthorizedError(response: HTTPURLResponse) | ||
case forbiddenError(response: HTTPURLResponse) | ||
case apiTooManyRequestsError(response: HTTPURLResponse) | ||
case unexpectedResponseError(response: HTTPURLResponse) | ||
case waitingRetryLater(date: Date?) | ||
} |
13 changes: 13 additions & 0 deletions
13
Sources/go-feature-flag-provider/exception/option_exceptions.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by thomas.poignant on 27/06/2024. | ||
// | ||
|
||
import Foundation | ||
|
||
enum InvalidOptions: Error { | ||
case invalidEndpoint(message: String) | ||
|
||
} |
Oops, something went wrong.