github.com/xmidt-org/webpa-common@v1.11.9/secure/key/resolverFactory.go (about)

     1  package key
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/xmidt-org/webpa-common/concurrent"
     8  	"github.com/xmidt-org/webpa-common/resource"
     9  )
    10  
    11  const (
    12  	// KeyIdParameterName is the template parameter that must be present in URI templates
    13  	// if there are any parameters.  URI templates accepted by this package have either no parameters
    14  	// or exactly one (1) parameter with this name.
    15  	KeyIdParameterName = "keyId"
    16  )
    17  
    18  var (
    19  	// ErrorInvalidTemplate is the error returned when a URI template is invalid for a key resource
    20  	ErrorInvalidTemplate = fmt.Errorf(
    21  		"Key resource template must support either no parameters are the %s parameter",
    22  		KeyIdParameterName,
    23  	)
    24  )
    25  
    26  // ResolverFactory provides a JSON representation of a collection of keys together
    27  // with a factory interface for creating distinct Resolver instances.
    28  //
    29  // This factory uses resource.NewExpander() to create a resource template used in resolving keys.
    30  // This template can have no parameters, in which case the same resource is used regardless
    31  // of the key id.  If the template has any parameters, it must have exactly (1) parameter
    32  // and that parameter's name must be equal to KeyIdParameterName.
    33  type ResolverFactory struct {
    34  	resource.Factory
    35  
    36  	// All keys resolved by this factory will have this purpose, which affects
    37  	// how keys are parsed.
    38  	Purpose Purpose `json:"purpose"`
    39  
    40  	// UpdateInterval specifies how often keys should be refreshed.
    41  	// If negative or zero, keys are never refreshed and are cached forever.
    42  	UpdateInterval time.Duration `json:"updateInterval"`
    43  
    44  	// Parser is a custom key parser.  If omitted, DefaultParser is used.
    45  	Parser Parser `json:"-"`
    46  }
    47  
    48  func (factory *ResolverFactory) parser() Parser {
    49  	if factory.Parser != nil {
    50  		return factory.Parser
    51  	}
    52  
    53  	return DefaultParser
    54  }
    55  
    56  // NewResolver() creates a Resolver using this factory's configuration.  The
    57  // returned Resolver always caches keys forever once they have been loaded.
    58  func (factory *ResolverFactory) NewResolver() (Resolver, error) {
    59  	expander, err := factory.NewExpander()
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	names := expander.Names()
    65  	nameCount := len(names)
    66  	if nameCount == 0 {
    67  		// the template had no parameters, so we can create a simpler object
    68  		loader, err := factory.NewLoader()
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  
    73  		return &singleCache{
    74  			basicCache{
    75  				delegate: &singleResolver{
    76  					basicResolver: basicResolver{
    77  						parser:  factory.parser(),
    78  						purpose: factory.Purpose,
    79  					},
    80  					loader: loader,
    81  				},
    82  			},
    83  		}, nil
    84  	} else if nameCount == 1 && names[0] == KeyIdParameterName {
    85  		return &multiCache{
    86  			basicCache{
    87  				delegate: &multiResolver{
    88  					basicResolver: basicResolver{
    89  						parser:  factory.parser(),
    90  						purpose: factory.Purpose,
    91  					},
    92  					expander: expander,
    93  				},
    94  			},
    95  		}, nil
    96  	}
    97  
    98  	return nil, ErrorInvalidTemplate
    99  }
   100  
   101  // NewUpdater uses this factory's configuration to conditionally create a Runnable updater
   102  // for the given resolver.  This method delegates to the NewUpdater function, and may
   103  // return a nil Runnable if no updates are necessary.
   104  func (factory *ResolverFactory) NewUpdater(resolver Resolver) concurrent.Runnable {
   105  	return NewUpdater(time.Duration(factory.UpdateInterval), resolver)
   106  }