github.com/prebid/prebid-server/v2@v2.18.0/schain/schainwriter.go (about)

     1  package schain
     2  
     3  import (
     4  	"github.com/prebid/openrtb/v20/openrtb2"
     5  	"github.com/prebid/prebid-server/v2/openrtb_ext"
     6  	"github.com/prebid/prebid-server/v2/util/jsonutil"
     7  )
     8  
     9  // NewSChainWriter creates an ORTB 2.5 schain writer instance
    10  func NewSChainWriter(reqExt *openrtb_ext.ExtRequest, hostSChainNode *openrtb2.SupplyChainNode) (*SChainWriter, error) {
    11  	if !extPrebidSChainExists(reqExt) {
    12  		return &SChainWriter{hostSChainNode: hostSChainNode}, nil
    13  	}
    14  
    15  	sChainsByBidder, err := BidderToPrebidSChains(reqExt.Prebid.SChains)
    16  	if err != nil {
    17  		return nil, err
    18  	}
    19  
    20  	writer := SChainWriter{
    21  		sChainsByBidder: sChainsByBidder,
    22  		hostSChainNode:  hostSChainNode,
    23  	}
    24  	return &writer, nil
    25  }
    26  
    27  // SChainWriter is used to write the appropriate schain for a particular bidder defined in the ORTB 2.5 multi-schain
    28  // location (req.ext.prebid.schain) to the ORTB 2.5 location (req.source.ext)
    29  type SChainWriter struct {
    30  	sChainsByBidder map[string]*openrtb2.SupplyChain
    31  	hostSChainNode  *openrtb2.SupplyChainNode
    32  }
    33  
    34  // Write selects an schain from the multi-schain ORTB 2.5 location (req.ext.prebid.schains) for the specified bidder
    35  // and copies it to the ORTB 2.5 location (req.source.ext). If no schain exists for the bidder in the multi-schain
    36  // location and no wildcard schain exists, the request is not modified.
    37  func (w SChainWriter) Write(req *openrtb2.BidRequest, bidder string) {
    38  	const sChainWildCard = "*"
    39  	var selectedSChain *openrtb2.SupplyChain
    40  
    41  	wildCardSChain := w.sChainsByBidder[sChainWildCard]
    42  	bidderSChain := w.sChainsByBidder[bidder]
    43  
    44  	// source should not be modified
    45  	if bidderSChain == nil && wildCardSChain == nil && w.hostSChainNode == nil {
    46  		return
    47  	}
    48  
    49  	selectedSChain = &openrtb2.SupplyChain{Ver: "1.0"}
    50  
    51  	if bidderSChain != nil {
    52  		selectedSChain = bidderSChain
    53  	} else if wildCardSChain != nil {
    54  		selectedSChain = wildCardSChain
    55  	}
    56  
    57  	schain := openrtb_ext.ExtRequestPrebidSChain{
    58  		SChain: *selectedSChain,
    59  	}
    60  
    61  	if req.Source == nil {
    62  		req.Source = &openrtb2.Source{}
    63  	} else {
    64  		sourceCopy := *req.Source
    65  		req.Source = &sourceCopy
    66  	}
    67  
    68  	if w.hostSChainNode != nil {
    69  		schain.SChain.Nodes = append(schain.SChain.Nodes, *w.hostSChainNode)
    70  	}
    71  
    72  	sourceExt, err := jsonutil.Marshal(schain)
    73  	if err == nil {
    74  		req.Source.Ext = sourceExt
    75  	}
    76  }
    77  
    78  // extPrebidSChainExists checks if an schain exists in the ORTB 2.5 req.ext.prebid.schain location
    79  func extPrebidSChainExists(reqExt *openrtb_ext.ExtRequest) bool {
    80  	return reqExt != nil && reqExt.Prebid.SChains != nil
    81  }