Skip to content

Commit

Permalink
UOE-11191: Refactor: consume StoreURL from New portal UI and forward …
Browse files Browse the repository at this point in the history
…appstoreurl and appsource for applovinmax (#925)

* UOE-11191: Refactor: consume StoreURL from New portal UI and forward appstoreurl and appsource for applovinmax

* review comment

* UOE-11185: Stats for parsing failed for ituneid

* go fmt update
  • Loading branch information
AvinashKapre authored Oct 9, 2024
1 parent dee6692 commit 131439b
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 47 deletions.
59 changes: 35 additions & 24 deletions modules/pubmatic/openwrap/beforevalidationhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,10 @@ func (m OpenWrap) handleBeforeValidationHook(
}

if rCtx.Endpoint == models.EndpointAppLovinMax && payload.BidRequest.App != nil && payload.BidRequest.App.StoreURL == "" {
rCtx.AppLovinMax.AppStoreUrl = getProfileAppStoreUrlAndUpdateItunesID(rCtx, payload.BidRequest, impExt)
var isValidAppStoreUrl bool
if rCtx.AppLovinMax.AppStoreUrl, isValidAppStoreUrl = getProfileAppStoreUrl(rCtx); isValidAppStoreUrl {
m.updateSkadnSourceapp(rCtx, payload.BidRequest, impExt)
}
rCtx.PageURL = rCtx.AppLovinMax.AppStoreUrl
}
impExt.Wrapper = nil
Expand Down Expand Up @@ -1344,36 +1347,44 @@ func isValidURL(urlVal string) bool {
return validator.IsRequestURL(urlVal) && validator.IsURL(urlVal)
}

func getProfileAppStoreUrlAndUpdateItunesID(rctx models.RequestCtx, bidRequest *openrtb2.BidRequest, impExt *models.ImpExtension) string {
func getProfileAppStoreUrl(rctx models.RequestCtx) (string, bool) {
isValidAppStoreUrl := false
appStoreUrl := rctx.PartnerConfigMap[models.VersionLevelConfigID][models.AppStoreUrl]
if appStoreUrl == "" {
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [Error]: app storeurl not present in DB", rctx.PubID, rctx.ProfileID)
return appStoreUrl
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [Error]: app store url not present in DB", rctx.PubID, rctx.ProfileID)
return appStoreUrl, isValidAppStoreUrl
}
appStoreUrl = strings.TrimSpace(appStoreUrl)
if !isValidURL(appStoreUrl) {
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [AppStoreUrl]: %s [Error]: Invalid app storeurl", rctx.PubID, rctx.ProfileID, appStoreUrl)
return appStoreUrl
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [AppStoreUrl]: %s [Error]: Invalid app store url", rctx.PubID, rctx.ProfileID, appStoreUrl)
return appStoreUrl, isValidAppStoreUrl
}
var err error
if bidRequest.Device != nil && strings.ToLower(bidRequest.Device.OS) == "ios" {
//no multiple imp supported for AppLovinMax
if impExt != nil {
if impExt.SKAdnetwork == nil {
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [Error]: skadn is missing in imp.ext", rctx.PubID, rctx.ProfileID, appStoreUrl)
return appStoreUrl
}
var itunesID string
if itunesID = extractItunesIdFromAppStoreUrl(appStoreUrl); itunesID == "" {
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [AppStoreUrl]: %s [Error]: itunes id is missing in app store url", rctx.PubID, rctx.ProfileID, appStoreUrl)
return appStoreUrl
}
if impExt.SKAdnetwork, err = jsonparser.Set(impExt.SKAdnetwork, []byte(strconv.Quote(itunesID)), "sourceapp"); err != nil {
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [AppStoreUrl]: %s [Error]: %s", rctx.PubID, rctx.ProfileID, appStoreUrl, err.Error())
}
}
isValidAppStoreUrl = true
return appStoreUrl, isValidAppStoreUrl
}

func (m *OpenWrap) updateSkadnSourceapp(rctx models.RequestCtx, bidRequest *openrtb2.BidRequest, impExt *models.ImpExtension) {
if bidRequest.Device == nil || strings.ToLower(bidRequest.Device.OS) != "ios" {
return
}

if impExt == nil || impExt.SKAdnetwork == nil {
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [Error]: skadn is missing in imp.ext", rctx.PubID, rctx.ProfileID)
return
}

itunesID := extractItunesIdFromAppStoreUrl(rctx.AppLovinMax.AppStoreUrl)
if itunesID == "" {
m.metricEngine.RecordFailedParsingItuneID(rctx.PubIDStr, rctx.ProfileIDStr)
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [AppStoreUrl]: %s [Error]: itunes id is missing in app store url", rctx.PubID, rctx.ProfileID, rctx.AppLovinMax.AppStoreUrl)
return
}

if updatedSKAdnetwork, err := jsonparser.Set(impExt.SKAdnetwork, []byte(strconv.Quote(itunesID)), "sourceapp"); err != nil {
glog.Errorf("[AppLovinMax] [PubID]: %d [ProfileID]: %d [AppStoreUrl]: %s [Error]: %s", rctx.PubID, rctx.ProfileID, rctx.AppLovinMax.AppStoreUrl, err.Error())
} else {
impExt.SKAdnetwork = updatedSKAdnetwork
}
return appStoreUrl
}

func extractItunesIdFromAppStoreUrl(url string) string {
Expand Down
123 changes: 100 additions & 23 deletions modules/pubmatic/openwrap/beforevalidationhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6572,37 +6572,83 @@ func TestSetImpBidFloorParams(t *testing.T) {
}
}

func TestUpdateProfileAppStoreUrl(t *testing.T) {
func TestGetProfileAppStoreUrl(t *testing.T) {
type args struct {
rctx models.RequestCtx
}
tests := []struct {
name string
rctx models.RequestCtx
bidRequest *openrtb2.BidRequest
impExt *models.ImpExtension
wantAppStoreURL string
wantSourceApp string
name string
args args
want string
want1 bool
}{
{
name: "AppStoreUrl missing in DB",
rctx: models.RequestCtx{
PartnerConfigMap: map[int]map[string]string{
models.VersionLevelConfigID: {},
args: args{
rctx: models.RequestCtx{
PartnerConfigMap: map[int]map[string]string{
models.VersionLevelConfigID: {},
},
},
},
bidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}},
wantAppStoreURL: "",
want: "",
want1: false,
},
{
name: "Invalid AppStoreUrl",
rctx: models.RequestCtx{
PartnerConfigMap: map[int]map[string]string{
models.VersionLevelConfigID: {
models.AppStoreUrl: "invalid-url",
args: args{
rctx: models.RequestCtx{
PartnerConfigMap: map[int]map[string]string{
models.VersionLevelConfigID: {
models.AppStoreUrl: "invalid-url",
},
},
},
},
want: "invalid-url",
want1: false,
},
{
name: "Valid AppStoreUrl",
args: args{
rctx: models.RequestCtx{
PartnerConfigMap: map[int]map[string]string{
models.VersionLevelConfigID: {
models.AppStoreUrl: "https://apps.apple.com/app/id123456789",
},
},
},
},
bidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}},
wantAppStoreURL: "invalid-url",
want: "https://apps.apple.com/app/id123456789",
want1: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := getProfileAppStoreUrl(tt.args.rctx)
assert.Equal(t, tt.want, got)
assert.Equal(t, tt.want1, got1)
})
}
}

func TestUpdateSkadnSourceapp(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

type feilds struct {
m *OpenWrap
}
tests := []struct {
name string
rctx models.RequestCtx
bidRequest *openrtb2.BidRequest
impExt *models.ImpExtension
wantAppStoreURL string
wantSourceApp string
fe feilds
setup func() *mock_metrics.MockMetricsEngine
}{
{
name: "Valid AppStoreUrl os is ios and SKAdnetwork is present in imp.ext",
rctx: models.RequestCtx{
Expand All @@ -6611,6 +6657,9 @@ func TestUpdateProfileAppStoreUrl(t *testing.T) {
models.AppStoreUrl: "https://apps.apple.com/app/id123456789",
},
},
AppLovinMax: models.AppLovinMax{
AppStoreUrl: "https://apps.apple.com/app/id123456789",
},
},
bidRequest: &openrtb2.BidRequest{
App: &openrtb2.App{},
Expand All @@ -6626,6 +6675,9 @@ func TestUpdateProfileAppStoreUrl(t *testing.T) {
impExt: &models.ImpExtension{
SKAdnetwork: json.RawMessage(`{}`),
},
setup: func() *mock_metrics.MockMetricsEngine {
return mock_metrics.NewMockMetricsEngine(ctrl)
},
wantAppStoreURL: "https://apps.apple.com/app/id123456789",
wantSourceApp: "123456789",
},
Expand All @@ -6634,9 +6686,12 @@ func TestUpdateProfileAppStoreUrl(t *testing.T) {
rctx: models.RequestCtx{
PartnerConfigMap: map[int]map[string]string{
models.VersionLevelConfigID: {
models.AppStoreUrl: "https://apps.apple.com/app/id123456789",
models.AppStoreUrl: "https://apps.apple.com/app/id",
},
},
AppLovinMax: models.AppLovinMax{
AppStoreUrl: "https://apps.apple.com/app/id",
},
},
bidRequest: &openrtb2.BidRequest{
App: &openrtb2.App{},
Expand All @@ -6649,7 +6704,10 @@ func TestUpdateProfileAppStoreUrl(t *testing.T) {
},
},
},
wantAppStoreURL: "https://apps.apple.com/app/id123456789",
setup: func() *mock_metrics.MockMetricsEngine {
return mock_metrics.NewMockMetricsEngine(ctrl)
},
wantAppStoreURL: "https://apps.apple.com/app/id",
},
{
name: "Valid AppStoreUrl os is ios but SKAdnetwork missing in imp.ext",
Expand All @@ -6659,6 +6717,9 @@ func TestUpdateProfileAppStoreUrl(t *testing.T) {
models.AppStoreUrl: "https://apps.apple.com/app/id123456789",
},
},
AppLovinMax: models.AppLovinMax{
AppStoreUrl: "https://apps.apple.com/app/id123456789",
},
},
bidRequest: &openrtb2.BidRequest{
App: &openrtb2.App{},
Expand All @@ -6671,17 +6732,25 @@ func TestUpdateProfileAppStoreUrl(t *testing.T) {
},
},
},
setup: func() *mock_metrics.MockMetricsEngine {
return mock_metrics.NewMockMetricsEngine(ctrl)
},
impExt: &models.ImpExtension{},
wantAppStoreURL: "https://apps.apple.com/app/id123456789",
},
{
name: "Valid AppStoreUrl os is ios but Itunes ID missing in AppStoreUrl",
name: "Valid AppStoreUrl os is ios but Itunes ID missing in AppStoreUrl(url is of Android)",
rctx: models.RequestCtx{
PartnerConfigMap: map[int]map[string]string{
models.VersionLevelConfigID: {
models.AppStoreUrl: "https://apps.apple.com/app/",
},
},
AppLovinMax: models.AppLovinMax{
AppStoreUrl: "https://apps.apple.com/app/",
},
PubIDStr: "5890",
ProfileIDStr: "1234",
},
bidRequest: &openrtb2.BidRequest{
App: &openrtb2.App{},
Expand All @@ -6694,6 +6763,11 @@ func TestUpdateProfileAppStoreUrl(t *testing.T) {
},
},
},
setup: func() *mock_metrics.MockMetricsEngine {
mockEngine := mock_metrics.NewMockMetricsEngine(ctrl)
mockEngine.EXPECT().RecordFailedParsingItuneID("5890", "1234")
return mockEngine
},
impExt: &models.ImpExtension{
SKAdnetwork: json.RawMessage(`{}`),
},
Expand All @@ -6703,8 +6777,11 @@ func TestUpdateProfileAppStoreUrl(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotAppStoreURL := getProfileAppStoreUrlAndUpdateItunesID(tt.rctx, tt.bidRequest, tt.impExt)
assert.Equal(t, tt.wantAppStoreURL, gotAppStoreURL)
metricsEngine := tt.setup()
tt.fe.m = &OpenWrap{
metricEngine: metricsEngine,
}
tt.fe.m.updateSkadnSourceapp(tt.rctx, tt.bidRequest, tt.impExt)
if tt.impExt != nil {
if tt.impExt.SKAdnetwork != nil {
var skAdnetwork map[string]interface{}
Expand Down
7 changes: 7 additions & 0 deletions modules/pubmatic/openwrap/metrics/config/multimetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,3 +529,10 @@ func (me *MultiMetricsEngine) RecordSignalDataStatus(pubid, profileid, signalTyp
thisME.RecordSignalDataStatus(pubid, profileid, signalType)
}
}

// RecordFailedParsingItuneID record failed parsing itune id
func (me *MultiMetricsEngine) RecordFailedParsingItuneID(pubId, profId string) {
for _, thisME := range *me {
thisME.RecordFailedParsingItuneID(pubId, profId)
}
}
3 changes: 3 additions & 0 deletions modules/pubmatic/openwrap/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,7 @@ type MetricsEngine interface {
//VMAP-adrule
RecordAdruleEnabled(pubId, profId string)
RecordAdruleValidationFailure(pubId, profId string)

//AppLovinMax metrics
RecordFailedParsingItuneID(pubId, profId string)
}
12 changes: 12 additions & 0 deletions modules/pubmatic/openwrap/metrics/mock/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions modules/pubmatic/openwrap/metrics/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ type Metrics struct {
//VMAP adrule
pubProfAdruleEnabled *prometheus.CounterVec
pubProfAdruleValidationfailure *prometheus.CounterVec

//ApplovinMax
failedParsingItuneId *prometheus.CounterVec
}

const (
Expand Down Expand Up @@ -360,6 +363,12 @@ func newMetrics(cfg *config.PrometheusMetrics, promRegistry *prometheus.Registry
[]string{pubIdLabel, profileIDLabel},
)

metrics.failedParsingItuneId = newCounter(cfg, promRegistry,
"failed_parsing_itune_id",
"Count of failed parsing itune id",
[]string{pubIdLabel, profileIDLabel},
)

newSSHBMetrics(&metrics, cfg, promRegistry)

return &metrics
Expand Down Expand Up @@ -599,6 +608,14 @@ func (m *Metrics) RecordSignalDataStatus(pubid, profileid, signalType string) {
}).Inc()
}

func (m *Metrics) RecordFailedParsingItuneID(pubId, profId string) {
m.failedParsingItuneId.With(prometheus.Labels{
pubIDLabel: pubId,
profileIDLabel: profId,
}).Inc()

}

// TODO - really need ?
func (m *Metrics) RecordPBSAuctionRequestsStats() {}

Expand Down
1 change: 1 addition & 0 deletions modules/pubmatic/openwrap/metrics/stats/tcp_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,4 @@ func (st *StatsTCP) RecordSignalDataStatus(pubid, profileid, signalType string)
func (st *StatsTCP) RecordPrebidCacheRequestTime(success bool, length time.Duration) {}
func (st *StatsTCP) RecordPrebidAuctionBidResponse(publisher string, partnerName string, bidderCode string, adapterCode string) {
}
func (st *StatsTCP) RecordFailedParsingItuneID(pubId, profId string) {}

0 comments on commit 131439b

Please sign in to comment.