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

     1  package modules
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  
     7  	"github.com/golang/glog"
     8  	"github.com/prebid/prebid-server/config"
     9  	"github.com/prebid/prebid-server/hooks"
    10  	"github.com/prebid/prebid-server/modules/moduledeps"
    11  )
    12  
    13  //go:generate go run ./generator/buildergen.go
    14  
    15  // NewBuilder returns a new module builder.
    16  func NewBuilder() Builder {
    17  	return &builder{builders()}
    18  }
    19  
    20  // Builder is the interfaces intended for building modules
    21  // implementing hook interfaces [github.com/prebid/prebid-server/hooks/hookstage].
    22  type Builder interface {
    23  	// Build initializes existing hook modules passing them config and other dependencies.
    24  	// It returns hook repository created based on the implemented hook interfaces by modules
    25  	// and a map of modules to a list of stage names for which module provides hooks
    26  	// or an error encountered during module initialization.
    27  	Build(cfg config.Modules, client moduledeps.ModuleDeps) (hooks.HookRepository, map[string][]string, error)
    28  }
    29  
    30  type (
    31  	// ModuleBuilders mapping between module name and its builder: map[vendor]map[module]ModuleBuilderFn
    32  	ModuleBuilders map[string]map[string]ModuleBuilderFn
    33  	// ModuleBuilderFn returns an interface{} type that implements certain hook interfaces.
    34  	ModuleBuilderFn func(cfg json.RawMessage, deps moduledeps.ModuleDeps) (interface{}, error)
    35  )
    36  
    37  type builder struct {
    38  	builders ModuleBuilders
    39  }
    40  
    41  // Build walks over the list of registered modules and initializes them.
    42  //
    43  // The ID chosen for the module's hooks represents a fully qualified module path in the format
    44  // "vendor.module_name" and should be used to retrieve module hooks from the hooks.HookRepository.
    45  //
    46  // Method returns a hooks.HookRepository and a map of modules to a list of stage names
    47  // for which module provides hooks or an error occurred during modules initialization.
    48  func (m *builder) Build(
    49  	cfg config.Modules,
    50  	deps moduledeps.ModuleDeps,
    51  ) (hooks.HookRepository, map[string][]string, error) {
    52  	modules := make(map[string]interface{})
    53  	for vendor, moduleBuilders := range m.builders {
    54  		for moduleName, builder := range moduleBuilders {
    55  			var err error
    56  			var conf json.RawMessage
    57  			var isEnabled bool
    58  
    59  			id := fmt.Sprintf("%s.%s", vendor, moduleName)
    60  			if data, ok := cfg[vendor][moduleName]; ok {
    61  				if conf, err = json.Marshal(data); err != nil {
    62  					return nil, nil, fmt.Errorf(`failed to marshal "%s" module config: %s`, id, err)
    63  				}
    64  
    65  				if values, ok := data.(map[string]interface{}); ok {
    66  					if value, ok := values["enabled"].(bool); ok {
    67  						isEnabled = value
    68  					}
    69  				}
    70  			}
    71  
    72  			if !isEnabled {
    73  				glog.Infof("Skip %s module, disabled.", id)
    74  				continue
    75  			}
    76  
    77  			module, err := builder(conf, deps)
    78  			if err != nil {
    79  				return nil, nil, fmt.Errorf(`failed to init "%s" module: %s`, id, err)
    80  			}
    81  
    82  			modules[id] = module
    83  		}
    84  	}
    85  
    86  	collection, err := createModuleStageNamesCollection(modules)
    87  	if err != nil {
    88  		return nil, nil, err
    89  	}
    90  
    91  	repo, err := hooks.NewHookRepository(modules)
    92  
    93  	return repo, collection, err
    94  }