github.com/prebid/prebid-server@v0.275.0/schain/schainwriter.go (about)

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