-
Notifications
You must be signed in to change notification settings - Fork 765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ads.Cert Call Sign support #2241
Conversation
# Conflicts: # exchange/exchange.go
What kind of unit tests can be added here? |
Discussed unit tests offline. Will add them in next commit |
config/bidderinfo.go
Outdated
Experiment BidderInfoExperiment `yaml:"experiment"` | ||
} | ||
|
||
// BidderInfoExperiment specified non-production ready features. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: specified -> specifies
config/experiment.go
Outdated
//Url - address of grpc server | ||
Url string `mapstructure:"url"` | ||
//SigningTimeoutMs specifies how long this client will wait for signing to finish before abandoning | ||
SigningTimeoutMs int `mapstructure:"signing_timeout"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that you included the ms unit in the name. Could you please carry that over into the map structure name too so the unit is available in the config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed
docs/developers/adscertsigner.md
Outdated
@@ -0,0 +1,90 @@ | |||
##Ads Cert |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend moving this up to just /docs instead of /docs/developers. Make it easier to discover. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved
@@ -88,6 +88,7 @@ func BenchmarkOpenrtbEndpoint(b *testing.B) { | |||
func(ctx context.Context, id uint16) (vendorlist.VendorList, error) { return nil, nil }, | |||
currency.NewRateConverter(&http.Client{}, "", time.Duration(0)), | |||
empty_fetcher.EmptyFetcher{}, | |||
nil, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using a NilSigner here instead to document what the argument is for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, replaced in all occurrences
exchange/bidder_test.go
Outdated
@@ -704,8 +704,8 @@ func TestMultiCurrencies(t *testing.T) { | |||
1, | |||
currencyConverter.Rates(), | |||
&adapters.ExtraRequestInfo{}, | |||
true, | |||
true, | |||
nil, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for all of these tests. A NilSigner would be self-documenting and easier for the reader to understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, replaced in all occurrences
experiment/adscert/signer.go
Outdated
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} | ||
conn, err := grpc.Dial(remoteSignerConfig.Url, opts...) | ||
if err != nil { | ||
fmt.Errorf("failed to dial remote signer: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you're missing a return statement here. Consider adding a unit test. I don't know if that's feasible for the dialer code though. Maybe Google or StackOverflow know of some tricks to test something like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added return statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unit tests with fake input data fail with null pointer exception that I cannot "catch"
experiment/adscert/signer.go
Outdated
if err != nil { | ||
fmt.Errorf("failed to dial remote signer: %v", err) | ||
} | ||
//defer conn.Close() -- where this should be? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, this should be triggered when the app is gracefully shutting down. You might be able to just get away without it though, since the connections are expected to remain open for the life of the application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this should live and die with application. I removed this line :/
experiment/adscert/signer.go
Outdated
|
||
func (ns *NilSigner) Sign(destinationURL string, body []byte) (string, error) { | ||
return "", nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it would be a good idea to separate the in process signer, remote signer, and nil signer to their own files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separated In-Process and Remote signers to separate files. NilSigner is now in the same file with interface. Should I move it too?
experiment/adscert/signer_test.go
Outdated
assert.EqualError(t, err, "Test error", "incorrect error") | ||
} else { | ||
if test.operationStatusOk { | ||
assert.NoError(t, err, "error should not be returned") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO there is no need to include an error message like "error should not be returned" since that's pretty obvious in the test results. I usually include the name/description of the test case and what i'm asserting to help with debugging, since those will not automatically appear in the test results.
# Conflicts: # config/config.go # exchange/exchange.go
config/experiment.go
Outdated
|
||
// AdsCertInProcess configures data to sign requests using ads certs library in core PBS logic | ||
type AdsCertInProcess struct { | ||
//Origin is ads.cert hostname for the originating party |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: Please add a space before the comment (ie // Origin
) for the field comments for AdsCertInProcess
and AdsCertRemote
.
exchange/bidder_test.go
Outdated
httpRequest: &adapters.RequestData{ | ||
Method: "POST", | ||
Uri: server.URL, | ||
Body: []byte("{\"key\":\"val\"}"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: You can use the backtick string notation here too.
exchange/exchange_test.go
Outdated
Adapters: make(map[string]config.Adapter, 1), | ||
} | ||
cfg.Adapters["appnexus"] = config.Adapter{ | ||
Endpoint: "test.com", //Note the '&' character in there |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a left over copy/paste? I don't see an & character.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy paste, yes, sorry, fixed.
exchange/exchange_test.go
Outdated
@@ -4073,6 +4074,132 @@ func TestAuctionDebugEnabled(t *testing.T) { | |||
|
|||
} | |||
|
|||
func TestExperimentConfigs(t *testing.T) { | |||
//This test just pass experiment ads cert configs to HoldAuction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider choosing a more descriptive test name and removing the comment. Looks like the test assets and error, but is that a real error from trying to determine if test.com has a call sign registered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to TestPassExperimentConfigsToHoldAuction
. This test runs HoldAuction with MockSigner and only tests correct data was passed to the signer.
} | ||
|
||
func validateInProcessSignerConfig(inProcessSignerConfig config.AdsCertInProcess) error { | ||
_, err := url.ParseRequestURI(inProcessSignerConfig.Origin) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe all config validation logic is currently in config.fo, so it moving it there would keep it central
I understand about knowing which side to configure. I didn't focus on that before. Perhaps we need to change Enabled to Mode (or some such, whatever language we use elsewhere) which can be something like "off", "inprocess" or "remote". Then we know exactly the host's intent on which one to validate, and also perhaps that the other choice has not been configured.
experiment/adscert/remotesigner.go
Outdated
return nil, err | ||
} | ||
// Establish the gRPC connection that the client will use to connect to the | ||
// signatory server. Authenticated connections are not implemented at this time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eeek! This now reads "Authenticated connections are not implemented at this time" .. but the problem is this PR is literally implementing "ads.cert authenticated connections". Sorry for misguiding you here. How about:
Secure connections are not implemented at this time.
experiment/adscert/signer.go
Outdated
errBothSignersSpecified = errors.New("both inprocess and remote signers are specified. Please use just one signer") | ||
) | ||
|
||
//Signer represents interface to access request Ads Cert signing functionality |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: Add space at the start of the comment.
Modified config from |
config/config.go
Outdated
ErrInvalidRemoteSignerURL = errors.New("invalid url for remote signer") | ||
ErrInvalidRemoteSignerSigningTimeout = errors.New("invalid signing timeout for remote signer") | ||
|
||
AdCertsSignerModeOff = "off" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it make more sense to have these defined as constants?
Also, I'd recommend moving all these values to experiment.go since they are AdsCert specific and all the other AdsCert specific structs live there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to experiment.go. Extracted to constants.
config/config.go
Outdated
@@ -139,6 +156,41 @@ type AuctionTimeouts struct { | |||
Max uint64 `mapstructure:"max"` | |||
} | |||
|
|||
func (cfg *Experiment) validate(errs []error) []error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also move this validate
method over to experiment.go since the Experiment
struct is defined there. I'd group the struct and the methods on that struct in the same file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, moved
config/config.go
Outdated
if cfg.AdCerts.Mode == AdCertsSignerModeInprocess { | ||
_, err := url.ParseRequestURI(cfg.AdCerts.InProcess.Origin) | ||
if err != nil { | ||
errs = append(errs, ErrInProcessSignerInvalidURL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend appending the actual values that are set in the config to the error messages so that it's clear from the error message why that value is invalid. You'll see similar behavior in other config validate
functions as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is how it was before and modified due to this discussion: #2241 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
appending the actual values
- I read it like appending actual error strings to array. Modified
@@ -164,6 +172,13 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde | |||
if reqInfo.GlobalPrivacyControlHeader == "1" { | |||
reqData[i].Headers.Add("Sec-GPC", reqInfo.GlobalPrivacyControlHeader) | |||
} | |||
if bidRequestMetadata.addCallSignHeader { | |||
signatureMessage, err := adCertSigner.Sign(reqData[i].Uri, reqData[i].Body) | |||
if err == nil && len(signatureMessage) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate PR sounds good to me 👍 @VeronikaSolovei9 would you mind just modifying the comment to add a warning message in debug mode as well in addition to the metrics please? Just so that we don't forget about it
Looking pretty close to me other than the very few minor comments above |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM except for the above minor comment regarding the test
config/experiment_test.go
Outdated
@@ -98,15 +101,15 @@ func TestExperimentValidate(t *testing.T) { | |||
AdCerts: ExperimentAdsCert{Mode: AdCertsSignerModeInprocess, InProcess: AdsCertInProcess{Origin: "http://test.com", PrivateKey: "pk", DNSCheckIntervalInSeconds: -10, DNSRenewalIntervalInSeconds: 10}}, | |||
}, | |||
expectErrors: true, | |||
expectedErrors: []error{ErrInProcessSignerInvalidDNSCheckInterval}, | |||
expectedErrors: []error{fmt.Errorf("invalid dns check interval for inprocess signer: -10")}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fmt.Errorf
should be used when you have a formatted error string i.e. when you're using %s
, %d
, etc for which the values are going to filled in run time. Here for expectedErrors
you already have a constant string that you're expecting so you can just use errors.New
.
Same for L112, L123 and L124
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, I missed it accidentally. Fixed.
Call Sign support for Prebid Server. For more info refer to adscertsigner.md