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