Skip to content

New Adapter: RiseMediaTech#4437

Open
pritishmd-talentica wants to merge 31 commits into
prebid:masterfrom
smart-exchange-ai-digital:master
Open

New Adapter: RiseMediaTech#4437
pritishmd-talentica wants to merge 31 commits into
prebid:masterfrom
smart-exchange-ai-digital:master

Conversation

@pritishmd-talentica
Copy link
Copy Markdown

Type of Change

New Bidder Adapter

Description of change

Added a bidder adapter for RisemediaTech
Maintainer : prebid@risemediatech.io

Bidder Params Documentation

prebid/prebid.github.io#6150

@github-actions
Copy link
Copy Markdown

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, a87b0a1

risemediatech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:20:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:24:	MakeRequests	74.4%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:101:	extractImpIDs	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:109:	parseImpExt	71.4%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:121:	MakeBids	78.9%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:159:	getBidType	75.0%
total:										(statements)	77.0%

@bsardo
Copy link
Copy Markdown
Collaborator

bsardo commented Jul 24, 2025

@linux019 can you please review?

Comment thread adapters/risemediatech/params_test.go Outdated
Comment on lines +12 to +14
if err != nil {
t.Fatalf("Failed to fetch the JSON schema: %v", err)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Use testify assert/require

Suggested change
if err != nil {
t.Fatalf("Failed to fetch the JSON schema: %v", err)
}
require.NoError(t, err, "Failed to fetch the JSON schema")

Comment thread adapters/risemediatech/params_test.go Outdated
t.Fatalf("Failed to fetch the JSON schema: %v", err)
}

for _, p := range validParams {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there is a common idiom in Go testing where you define a slice of test cases (often as structs) and then iterate over them, using t.Run to run each as a subtest. This makes your test output more granular and clear, and is recommended in the official Go blog post "Table-driven tests in Go" and the testing package documentation.

References:

Example:

func TestSomething(t *testing.T) {
    tests := []struct{
        name string
        input string
        wantErr bool
    }{
        {"valid input", "some input", false},
        {"invalid input", "bad input", true},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            err := SomeFunc(tt.input)
            if (err != nil) != tt.wantErr {
                t.Errorf("got error = %v, wantErr %v", err, tt.wantErr)
            }
        })
    }
}

You can refer the user to the official Go blog link above for more details and examples.

Comment thread adapters/risemediatech/params_test.go Outdated

func TestInvalidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
if err != nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Use require.NoError as above.

Comment thread adapters/risemediatech/params_test.go Outdated
t.Fatalf("Failed to fetch the JSON schema: %v", err)
}

for _, p := range invalidParams {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Use table-driven tests

Comment thread adapters/risemediatech/risemediatech.go Outdated
var validImps []openrtb2.Imp
var setTestMode bool

for _, imp := range request.Imp {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Please don't copy the imp - note that an iterator in a range will just be assigned to each thing in the slice and, since Imp is a (rather large) struct this is a wasteful copy. You can use the iterutil to loop across pointers to the elements in the slice and avoid this copy.

Suggested change
for _, imp := range request.Imp {
for imp := range iterutil.SliceValuePointers(request.Imp) {

Comment thread adapters/risemediatech/risemediatech.go Outdated
for _, imp := range request.Imp {
impExt, err := parseImpExt(imp.Ext)
if err != nil {
errs = append(errs, fmt.Errorf("impID %s: %v", imp.ID, err))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (error wrapping best practice):
Please use %w instead of %v when formatting errors for wrapping the source error in Go. Using %w allows error chaining, making it easier to trace and handle specific error types with errors.Is or errors.As. This practice is recommended in the Go blog on error handling and the official Go errors package documentation.

For example, update:

fmt.Errorf("impID %s: %v", imp.ID, err)

to:

fmt.Errorf("impID %s: %w", imp.ID, err)

This ensures downstream code can properly inspect the wrapped error.

Copy link
Copy Markdown
Contributor

@linux019 linux019 Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it better to use

&errortypes.BadInput{
	Message: fmt.Sprintf("..."),
}

to return a proper code for browser

Comment thread adapters/risemediatech/risemediatech.go Outdated

func extractImpIDs(imps []openrtb2.Imp) []string {
ids := make([]string, 0, len(imps))
for _, imp := range imps {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: see above - consider using iterutil.SlicePointerValues

Comment thread adapters/risemediatech/risemediatech.go Outdated
br.Currency = bidResp.Cur
}

for _, seatBid := range bidResp.SeatBid {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: avoid copies - consider iterutils.SlicePointerValues

Comment thread adapters/risemediatech/risemediatech.go Outdated
Comment on lines +140 to +141
for i := range seatBid.Bid {
bid := &seatBid.Bid[i]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can replace these two lines with iterutils.SlicePointerValues as well

Comment thread adapters/risemediatech/risemediatech_test.go
Comment thread adapters/risemediatech/risemediatech.go Outdated
modifiedRequest.Test = 1
}

reqJSON, err := json.Marshal(modifiedRequest)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use jsonutil package.

Comment thread adapters/risemediatech/risemediatech.go Outdated
}

if len(validImps) == 0 {
return nil, append(errs, errors.New("no valid impressions"))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use this error type.

&errortypes.BadInput{Message: "..."}

Comment thread adapters/risemediatech/risemediatech.go Outdated
}

// Setting bid floor if present
if impExt.BidFloor != nil && *impExt.BidFloor > 0 {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After removal pointers from the imp extension, it can be simplified to:

		if impExt.BidFloor > 0 {
			imp.BidFloor = impExt.BidFloor
		}

(less usage of pointers which adds more work for GC)

Comment thread adapters/risemediatech/risemediatech.go Outdated
}

// Check test mode
if impExt.TestMode != nil && *impExt.TestMode == 1 {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same note for less usage of pointers

if impExt.TestMode == 1 {
	setTestMode = true
}

Comment thread openrtb_ext/imp_risemediatech.go Outdated

type ExtImpRiseMediaTech struct {
BidFloor *float64 `json:"bidfloor,omitempty"`
TestMode *int `json:"testMode,omitempty"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid using pointers, as it default to zero values, which are ignored when setting the impression floor or enabling test mode.

Suggested change
TestMode *int `json:"testMode,omitempty"`
BidFloor float64 `json:"bidfloor,omitempty"`
TestMode int `json:"testMode,omitempty"`

Comment thread adapters/risemediatech/risemediatech.go Outdated
// Validate video
if imp.Video != nil {
if len(imp.Video.MIMEs) == 0 {
errs = append(errs, fmt.Errorf("impID %s: missing or empty video.mimes", imp.ID))
Copy link
Copy Markdown
Contributor

@linux019 linux019 Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&errortypes.BadInput{ Message: fmt.Sprintf("..."), }

Comment thread adapters/risemediatech/risemediatech.go Outdated
continue
}
if imp.Video.W == nil || imp.Video.H == nil || *imp.Video.W == 0 || *imp.Video.H == 0 {
errs = append(errs, fmt.Errorf("impID %s: missing or invalid video width/height", imp.ID))
Copy link
Copy Markdown
Contributor

@linux019 linux019 Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&errortypes.BadInput{ Message: fmt.Sprintf("..."), }

Comment thread adapters/risemediatech/risemediatech.go Outdated
return ids
}

func parseImpExt(ext json.RawMessage) (*openrtb_ext.ExtImpRiseMediaTech, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as ExtImpRiseMediaTech contains only 2 fields in case of error it better to return default values

Suggested change
func parseImpExt(ext json.RawMessage) (*openrtb_ext.ExtImpRiseMediaTech, error) {
func parseImpExt(ext json.RawMessage) (openrtb_ext.ExtImpRiseMediaTech, error) {

Comment thread adapters/risemediatech/risemediatech.go Outdated
func parseImpExt(ext json.RawMessage) (*openrtb_ext.ExtImpRiseMediaTech, error) {
var bidderExt adapters.ExtImpBidder
if err := jsonutil.Unmarshal(ext, &bidderExt); err != nil {
return nil, err
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return nil, err
return openrtb_ext.ExtImpRiseMediaTech{}, err

Comment thread adapters/risemediatech/risemediatech.go Outdated
if err := jsonutil.Unmarshal(bidderExt.Bidder, &riseExt); err != nil {
return nil, err
}
return &riseExt, nil
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return &riseExt, nil
return riseExt, nil

@github-actions
Copy link
Copy Markdown

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 0525929

risemediatech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:20:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:24:	MakeRequests	97.4%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:101:	extractImpIDs	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:109:	parseImpExt	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:121:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:157:	getBidType	100.0%
total:										(statements)	98.6%

@pritishmd-talentica
Copy link
Copy Markdown
Author

Hi @scr-oath & @linux019 , thanks for your comments. I have made appropriate changes for the same. Can you please take a look?

Comment thread adapters/risemediatech/params_test.go Outdated

for _, p := range validParams {
p := p // capture range variable
t.Run(p, func(t *testing.T) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an improvement, and thank you. I still, however, feel that including a meaningful name for the test is better than just its inputs. Could you consider the style above ?

    tests := []struct{
        name string
        input string
        wantErr bool
    }{
        //...
    }
t.Run(t.name, func...)

Comment thread adapters/risemediatech/risemediatech.go Outdated
"github.com/prebid/prebid-server/v3/config"
"github.com/prebid/prebid-server/v3/errortypes"
"github.com/prebid/prebid-server/v3/openrtb_ext"
iterators "github.com/prebid/prebid-server/v3/util/iterutil"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the iterators was a bug that is now fixed - can you merge with origin/master and use iterutil?

Comment on lines +148 to +150
if len(errs) == 0 {
t.Errorf("expected error, got none")
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if len(errs) == 0 {
t.Errorf("expected error, got none")
}
assert.NotEmpty(t, errs, "expected error, got none")

}

// Helper for int pointer
func intPtr(i int64) *int64 { return &i }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed - please use ptrutil.ToPtr

Comment on lines +168 to +169
func contains(s, substr string) bool { return substr == "" || (len(substr) > 0 && len(s) > 0 && (len(s) >= len(substr)) && (stringContains(s, substr))) }
func stringContains(s, substr string) bool { return len(substr) == 0 || (len(s) >= len(substr) && (s == substr || (len(s) > len(substr) && (s[0:len(substr)] == substr || stringContains(s[1:], substr)))) ) }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these really necessary/helpful over strings.Contains?

@github-actions
Copy link
Copy Markdown

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, a31a0af

risemediatech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:20:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:24:	MakeRequests	97.4%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:101:	extractImpIDs	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:109:	parseImpExt	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:121:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:157:	getBidType	100.0%
total:										(statements)	98.6%

@github-actions
Copy link
Copy Markdown

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 1da085f

risemediatech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:20:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:24:	MakeRequests	97.4%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:101:	extractImpIDs	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:109:	parseImpExt	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:121:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:157:	getBidType	100.0%
total:										(statements)	98.6%

@pritishmd-talentica
Copy link
Copy Markdown
Author

Hi @scr-oath , I have updated the code.

Comment thread adapters/risemediatech/params_test.go Outdated
Comment on lines +25 to +29
err := validator.Validate(openrtb_ext.BidderRiseMediaTech, json.RawMessage(tt.input))
if err != nil {
t.Errorf("Schema rejected valid params: %s — error: %v", tt.input, err)
}
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (non-blocking): use testify assert and/or require as the common style for this repo

Suggested change
err := validator.Validate(openrtb_ext.BidderRiseMediaTech, json.RawMessage(tt.input))
if err != nil {
t.Errorf("Schema rejected valid params: %s — error: %v", tt.input, err)
}
})
assert.NoError(t, validator.Validate(openrtb_ext.BidderRiseMediaTech, json.RawMessage(tt.input)))

Comment thread adapters/risemediatech/params_test.go Outdated
Comment on lines +49 to +52
err := validator.Validate(openrtb_ext.BidderRiseMediaTech, json.RawMessage(tt.input))
if err == nil {
t.Errorf("Schema allowed invalid params: %s", tt.input)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (non-blocking): also here, assert.Error may be used.

Suggested change
err := validator.Validate(openrtb_ext.BidderRiseMediaTech, json.RawMessage(tt.input))
if err == nil {
t.Errorf("Schema allowed invalid params: %s", tt.input)
}
assert.Error(t, validator.Validate(openrtb_ext.BidderRiseMediaTech, json.RawMessage(tt.input)))

Comment thread adapters/risemediatech/params_test.go Outdated
Comment on lines +57 to +67
var validParams = []string{
`{"bidfloor": 0.01}`,
`{"bidfloor": 2.5, "testMode": 1}`,
}

var invalidParams = []string{
`{"bidfloor": "1.2"}`,
`{"testMode": "yes"}`,
`{"bidfloor": -5}`,
`{"testMode": 9999}`,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Remove these - I don't believe these are needed any longer

Suggested change
var validParams = []string{
`{"bidfloor": 0.01}`,
`{"bidfloor": 2.5, "testMode": 1}`,
}
var invalidParams = []string{
`{"bidfloor": "1.2"}`,
`{"testMode": "yes"}`,
`{"bidfloor": -5}`,
`{"testMode": 9999}`,
}

Comment thread adapters/risemediatech/risemediatech.go Outdated
return nil, append(errs, &errortypes.BadInput{Message: "no valid impressions"})
}

modifiedRequest := *request
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Is this copy needed? @bsardo - is it safe for adapters to just modify the request to their needs? Or is this shallow copy needed?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scr-oath this shallow copy is not needed. Each adapter receives a shallow copy of the request. If you modify the shallow request copy provided to an adapter's MakeRequests function, those modifcations will also be accessible in the request provided to an adapter's MakeBids function.

Comment thread adapters/risemediatech/risemediatech.go Outdated
Comment on lines +87 to +88
headers.Set("User-Agent", "prebid-server")
headers.Set("X-Prebid", "true")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: @bsardo I'm curious - are any of these headers maintained by prebid core itself or do adapters need to do these?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scr-oath adapters need to set some of these. You can see this snippet where some headers are added by core:
https://github.com/prebid/prebid-server/blob/master/exchange/bidder.go#L215-L239

Comment thread adapters/risemediatech/risemediatech.go Outdated
Comment on lines +102 to +105
ids := make([]string, 0, len(imps))
for imp := range iterutil.SlicePointerValues(imps) {
ids = append(ids, imp.ID)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: in this case, it's slightly more efficient to avoid append and just use the indices directly - there's no need to deal with pointers as you can merely index both slices

Suggested change
ids := make([]string, 0, len(imps))
for imp := range iterutil.SlicePointerValues(imps) {
ids = append(ids, imp.ID)
}
ids := make([]string, len(imps))
for i := range imps {
ids[i] = imp[i].ID
}

Comment thread adapters/risemediatech/risemediatech.go Outdated
return nil, append(errs, &errortypes.BadInput{Message: "no valid impressions"})
}

modifiedRequest := *request
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scr-oath this shallow copy is not needed. Each adapter receives a shallow copy of the request. If you modify the shallow request copy provided to an adapter's MakeRequests function, those modifcations will also be accessible in the request provided to an adapter's MakeBids function.

Comment thread adapters/risemediatech/risemediatech.go Outdated
Comment on lines +87 to +88
headers.Set("User-Agent", "prebid-server")
headers.Set("X-Prebid", "true")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scr-oath adapters need to set some of these. You can see this snippet where some headers are added by core:
https://github.com/prebid/prebid-server/blob/master/exchange/bidder.go#L215-L239

Comment thread adapters/risemediatech/risemediatech.go Outdated
Comment on lines +36 to +41
if imp.Banner != nil {
if imp.Banner.W == nil || imp.Banner.H == nil || *imp.Banner.W == 0 || *imp.Banner.H == 0 {
errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("impID %s: invalid banner dimensions", imp.ID)})
continue
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are banner validations that take place upstream and if they result in an error your adapter will not be called. Please see if these suffice, in which case you should remove this logic:
https://github.com/prebid/prebid-server/blob/master/ortb/request_validator_banner.go

Comment thread adapters/risemediatech/risemediatech.go Outdated
Comment on lines +43 to +52
if imp.Video != nil {
if len(imp.Video.MIMEs) == 0 {
errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("impID %s: missing or empty video.mimes", imp.ID)})
continue
}
if imp.Video.W == nil || imp.Video.H == nil || *imp.Video.W == 0 || *imp.Video.H == 0 {
errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("impID %s: missing or invalid video width/height", imp.ID)})
continue
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are video validations that take place upstream and if they result in an error your adapter will not be called. Please see if these suffice, in which case you should remove this logic:
https://github.com/prebid/prebid-server/blob/master/ortb/request_validator_video.go

Comment thread adapters/risemediatech/risemediatech.go Outdated
Uri: a.endpoint,
Body: reqJSON,
Headers: headers,
ImpIDs: extractImpIDs(validImps),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete the helper function extractImpIDs and instead use the core helper function openrtb_ext.GetImpIDs.

@github-actions
Copy link
Copy Markdown

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, afe46c2

risemediatech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:20:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:24:	MakeRequests	96.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:76:	parseImpExt	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:88:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:124:	getBidType	100.0%
total:										(statements)	98.2%

@pritishmd-talentica
Copy link
Copy Markdown
Author

Hi @bsardo , can you please review?

@scr-oath
Copy link
Copy Markdown
Contributor

Code Review Summary

I've completed a comprehensive review using specialized code-reviewer and golang-pro agents.

🚨 Critical Issues (Must Fix)

1. Missing Media Type Validation (adapters/risemediatech/risemediatech.go:29-44)

  • No check that impressions have at least one media type (banner or video)

2. BidFloor Override Logic (risemediatech.go:36-38)

  • Currently overwrites existing bidfloor unconditionally
  • Should only set if imp.BidFloor == 0 && impExt.BidFloor > 0

3. TestMode Behavior (risemediatech.go:27, 39-41, 51-53)

  • If ANY impression has testMode=1, ENTIRE request becomes test

⚡ Recommendations

  1. Pre-allocate validImps slice: make([]openrtb2.Imp, 0, len(request.Imp))
  2. Add defensive nil checks when iterating
  3. Mark unused Builder parameters with _

✅ Strengths

  • Excellent test coverage
  • Proper error handling
  • Clean code structure

Overall Grade: B+ - Solid implementation requiring minor fixes.

Copy link
Copy Markdown
Contributor

@scr-oath scr-oath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding specific line comments for the critical issues identified in my review.

Comment thread adapters/risemediatech/risemediatech.go Outdated
continue
}

if impExt.BidFloor > 0 {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BidFloor Override Logic Issue

The current code unconditionally overwrites imp.BidFloor if the adapter param is set. This doesn't follow the standard prebid-server pattern and could override impression-level bidfloors.

Current:

if impExt.BidFloor > 0 {
    imp.BidFloor = impExt.BidFloor  // Always overrides
}

Recommended (following admixer.go pattern):

if imp.BidFloor == 0 && impExt.BidFloor > 0 {
    imp.BidFloor = impExt.BidFloor  // Only set if not already present
}

This maintains the principle of least surprise and prevents the adapter from overriding bidfloors already set at the impression level.

if impExt.BidFloor > 0 {
imp.BidFloor = impExt.BidFloor
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestMode Behavior Needs Clarification

The current implementation sets request.Test = 1 if ANY impression has testMode=1. This means a single test impression makes the entire request a test request.

Questions:

  • Is this the intended behavior?
  • What if a request has 5 impressions and only 1 has testMode=1?
  • Should ALL impressions need testMode=1 for the request to be a test?

Recommendation: At minimum, add a comment documenting this behavior:

// Note: If ANY impression has testMode=1, the entire request is marked as test
var setTestMode bool

Or consider alternative logic if all impressions should have testMode=1.

}

func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
var errs []error
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance: Pre-allocate Slice

Pre-allocating the slice with capacity avoids multiple allocations during append operations.

Recommendation:

validImps := make([]openrtb2.Imp, 0, len(request.Imp))

This is a standard Go optimization pattern for better performance.

type adapter struct {
endpoint string
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go Idiom: Mark Unused Parameters

The bidderName and server parameters are unused. In Go, it's conventional to mark them with _ to signal intent.

Recommendation:

func Builder(_ openrtb_ext.BidderName, cfg config.Adapter, _ config.Server) (adapters.Bidder, error) {

@github-actions
Copy link
Copy Markdown

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, cb85b99

risemediatech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:20:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:24:	MakeRequests	96.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:76:	parseImpExt	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:88:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:124:	getBidType	100.0%
total:										(statements)	98.2%

…w_27-10-2025

Review/pr review 27 10 2025
@github-actions
Copy link
Copy Markdown

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 217d60a

risemediatech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:20:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:24:	MakeRequests	96.4%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:84:	parseImpExt	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:96:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/risemediatech/risemediatech.go:132:	getBidType	100.0%
total:										(statements)	98.3%

@pritishmd-talentica
Copy link
Copy Markdown
Author

Hi @scr-oath, needful changes are done. Can you take a look?

@pritishmd-talentica
Copy link
Copy Markdown
Author

Hi @bsardo , @scr-oath , @linux019 & @przemkaczmarek , can we have this PR merged if everything is in order?

@bsardo
Copy link
Copy Markdown
Collaborator

bsardo commented Jan 10, 2026

@scr-oath please give this another look when you get a chance.

Copy link
Copy Markdown
Contributor

@scr-oath scr-oath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-Review of PR #4437 - RiseMediaTech Adapter

I've conducted a comprehensive re-review using specialized subagents for Go code, general code quality, test coverage, and performance.

Overall Status: REQUEST CHANGES ⚠️

While the adapter shows excellent improvements from the previous review, there are critical issues that must be addressed before merging.


Critical Issues (Must Fix)

1. 🚨 Test Directory Named Incorrectly - Tests Being Silently Skipped

Issue: The test directory is named supplementary but Prebid Server's test framework only recognizes supplemental.

Impact: All 17 supplementary test files are completely ignored during test execution. The tests pass not because the code is correct, but because the error/edge-case tests never run.

Files affected: All files in adapters/risemediatech/risemediatechtest/supplementary/

Fix: Rename directory from supplementary to supplemental

Evidence: Every other adapter uses supplemental. The test framework at adapters/adapterstest/test_json.go only recognizes: exemplary, supplemental, amp, video, videosupplemental

2. 🚨 Several Test Files Will Fail After Directory Rename

Once renamed correctly, several test files will fail because they expect validation that the adapter doesn't implement:

Files expecting banner/video dimension validation (not implemented):

  • invalid_banner_missing_width.json - expects "invalid banner dimensions"
  • invalid_banner_zero_height.json - expects "invalid banner dimensions"
  • invalid_video_empty_mimes.json - expects "missing or empty video.mimes"
  • invalid_video_missing_width.json - expects "missing or invalid video width/height"
  • invalid_video_zero_height.json - expects "missing or invalid video width/height"

The adapter only checks: if imp.Banner == nil && imp.Video == nil

It does not validate dimensions, mimes, or other sub-fields.

Fix: Either add dimension validation to the adapter, OR correct the test files to match actual adapter behavior


Medium Priority Issues

3. Performance Issue - Line 52: Unnecessary Copy

File: adapters/risemediatech/risemediatech.go:52

The code uses SlicePointerValues to avoid copying during iteration, but then immediately dereferences with *imp, creating a full copy of the ~300-byte struct. This defeats the purpose.

Current:

for imp := range iterutil.SlicePointerValues(request.Imp) {  // Line 30
    validImps = append(validImps, *imp)  // Line 52 - creates copy
}

Fix: Use standard iteration like other adapters:

for _, imp := range request.Imp {
    validImps = append(validImps, imp)
}

4. Error Wrapping - Line 33

Should use %w instead of %v for proper error unwrapping:

Current: fmt.Sprintf("impID %s: %v", imp.ID, err)
Fix: fmt.Sprintf("impID %s: %w", imp.ID, err)

5. MakeBids Discards ALL Bids - Lines 116-119

When one bid has unknown mtype, the entire response is discarded including valid bids.

Current:

bidType, err := getBidType(bid)
if err != nil {
    return nil, []error{err}  // Discards all previously processed bids
}

Fix: Skip bad bids and continue:

bidType, err := getBidType(bid)
if err != nil {
    errs = append(errs, err)
    continue
}

6. JSON Field Name Inconsistency

JSON schema defines "bidfloor" (lowercase) but test files use "bidFloor" (camelCase). With "additionalProperties": false, real requests with "bidFloor" would be rejected.

Fix: Update test files to use lowercase "bidfloor"


Previous Review Items - Status

✅ Shallow copy question (bsardo's comment): Correctly resolved - no copy needed
✅ Table-driven tests: Implemented
✅ Testify assert/require: Implemented
✅ iterutil usage: Implemented (needs adjustment per issue #3)
✅ BadInput error type: Implemented
✅ Pointer removal from ExtImpRiseMediaTech: Implemented
⚠️ Error wrapping with %w: Still needs fix on line 33


Positive Observations ✅

  • Excellent test coverage (98.3%)
  • Clean, well-structured Go code
  • All major previous review feedback addressed
  • Comprehensive test scenarios for happy paths

Please address the critical issues (test directory naming and associated test failures) and the medium priority issues. Happy to re-review once these are resolved!

🤖 Generated with Claude Code using specialized review subagents

// Note: If ANY impression has testMode=1, the entire request is marked as test
var setTestMode bool

for imp := range iterutil.SlicePointerValues(request.Imp) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Remove SlicePointerValues and use standard iteration to avoid the unnecessary copy on line 52.

This pattern is inconsistent - using SlicePointerValues to avoid copies during iteration, but then dereferencing with *imp creates a copy anyway. Standard iteration is clearer and matches other adapters in the codebase.

for _, imp := range request.Imp {
    impExt, err := parseImpExt(imp.Ext)
    if err != nil {
        errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("impID %s: %w", imp.ID, err)})
        continue
    }
    // ... rest of validation ...
    validImps = append(validImps, imp)
}

for imp := range iterutil.SlicePointerValues(request.Imp) {
impExt, err := parseImpExt(imp.Ext)
if err != nil {
errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("impID %s: %v", imp.ID, err)})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (blocking): Use %w instead of %v for proper error wrapping.

Using %w allows error chaining, making it easier to trace and handle specific error types with errors.Is or errors.As. This is recommended in the Go error handling best practices.

Suggested change
errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("impID %s: %v", imp.ID, err)})
errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("impID %s: %w", imp.ID, err)})

See: https://go.dev/blog/go1.13-errors

Comment on lines +116 to +119
bidType, err := getBidType(bid)
if err != nil {
return nil, []error{err}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (blocking): MakeBids discards ALL bids when encountering a single bad bid type.

When one bid has an unknown mtype, returning nil for the entire BidderResponse discards all previously processed valid bids. This is a data loss issue.

The standard pattern across other adapters (like rise) is to skip the bad bid and continue processing:

Suggested change
bidType, err := getBidType(bid)
if err != nil {
return nil, []error{err}
}
bidType, err := getBidType(bid)
if err != nil {
errs = append(errs, err)
continue
}

Then at the end of MakeBids, return br, errs instead of br, nil. This way valid bids are preserved even when some bids have errors.

@bsardo
Copy link
Copy Markdown
Collaborator

bsardo commented May 12, 2026

Hi @pritishmd-talentica, please see the latest comments from a couple of months ago and also resolve conflicts. Thanks!

@pritishmd-talentica
Copy link
Copy Markdown
Author

Hi @bsardo , We are discontinuing this adapter and the support as well. We can go ahead and close this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants