func (m *Manager) CheckRequiredGroupChains() error {
	for k := range defaultGroupChains {
		if _, ok := m.groupProcesses[k]; !ok {
			m.log.Error("Missing required chain", "chain", k)
			return ErrUnknownHookChain
		}
		if len(m.groupProcesses[k]) == 0 {
			m.log.Error("A required chain is empty", "chain", k)
			return ErrEmptyHookChain
		}
	}
	return nil
}
CheckRequiredGroupChains searches for all chains in the default
chains list and logs a fatal error if one isn't found in the
configured list.  This allows the system to later assert the
presence of chains without checking, since they cannot be modified
after loading.
package tree
import (
	"sort"
	pb "github.com/netauth/protocol"
)
type GroupHookConstructor func(RefContext) (GroupHook, error)
type GroupHook interface {
	Priority() int
	Name() string
	Run(*pb.Group, *pb.Group) error
}
var (
	gHookConstructors map[string]GroupHookConstructor
)
func init() {
	gHookConstructors = make(map[string]GroupHookConstructor)
}
func RegisterGroupHookConstructor(name string, c GroupHookConstructor) {
	if _, ok := gHookConstructors[name]; ok {
		log().Trace("Duplicate GroupHookConstructor registration attempt", "hook", name)
		return
	}
	gHookConstructors[name] = c
	log().Trace("GroupHookConstructor registered", "constructor", name)
}
func (m *Manager) InitializeGroupHooks() {
	m.log.Debug("Executing GroupHookConstructor callbacks")
	for _, v := range gHookConstructors {
		hook, err := v(m.refContext)
		if err != nil {
			m.log.Warn("Error initializing hook", "hook", hook, "error", err)
			continue
		}
		m.groupHooks[hook.Name()] = hook
		m.log.Trace("GroupHook registered", "hook", hook.Name())
	}
}
func (m *Manager) InitializeGroupChains(c ChainConfig) error {
	for chain, hooks := range c {
		m.log.Debug("Initializing Group Chain", "chain", chain)
		for _, h := range hooks {
			if err := m.RegisterGroupHookToChain(h, chain); err != nil {
				return err
			}
		}
	}
	return nil
}
func (m *Manager) RegisterGroupHookToChain(hook, chain string) error {
	eph, ok := m.groupHooks[hook]
	if !ok {
		m.log.Warn("Missing hook during chain initializtion", "chain", chain, "hook", hook)
		return ErrUnknownHook
	}
	m.groupProcesses[chain] = append(m.groupProcesses[chain], eph)
	sort.Slice(m.groupProcesses[chain], func(i, j int) bool {
		return m.groupProcesses[chain][i].Priority() < m.groupProcesses[chain][j].Priority()
	})
	m.log.Trace("Registered hook to chain", "chain", chain, "hook", hook)
	return nil
}