Documentation
¶
Index ¶
- Constants
- Variables
- func AddAnnotationToData(d *pb.Data, aa *pb.AkitaAnnotations)
- func ContainsCLITraffic(w *pb.Witness) bool
- func DataMapKeys(fields map[string]*pb.Data) []string
- func EquivalentDataTemplates(sharedPrefix []*pb.MethodTemplate, dt1 *pb.DataTemplate, dt2 *pb.DataTemplate) (bool, error)
- func ExtractValueFromTemplate(t *pb.DataTemplate, ref *pb.DataRef) (*pb.Data, error)
- func FlattenAlternatives(alts map[string][]*pb.Data) []map[string]*pb.Data
- func GetDataRef(r *pb.DataRef, d *pb.Data) (*pb.Data, error)
- func HTTPAuthFromData(d *pb.Data) *pb.HTTPAuth
- func HTTPBodyFromData(d *pb.Data) *pb.HTTPBody
- func HTTPBodyFromTemplate(dt *pb.DataTemplate) *pb.HTTPBody
- func HTTPCookieFromData(d *pb.Data) *pb.HTTPCookie
- func HTTPCookieFromTemplate(dt *pb.DataTemplate) *pb.HTTPCookie
- func HTTPEmptyFromData(d *pb.Data) *pb.HTTPEmpty
- func HTTPHeaderFromData(d *pb.Data) *pb.HTTPHeader
- func HTTPHeaderFromTemplate(dt *pb.DataTemplate) *pb.HTTPHeader
- func HTTPMetaFromData(d *pb.Data) *pb.HTTPMeta
- func HTTPMetaFromMethod(m *pb.Method) *pb.HTTPMethodMeta
- func HTTPMultipartFromData(d *pb.Data) *pb.HTTPMultipart
- func HTTPPathFromData(d *pb.Data) *pb.HTTPPath
- func HTTPPathFromTemplate(dt *pb.DataTemplate) *pb.HTTPPath
- func HTTPQueryFromData(d *pb.Data) *pb.HTTPQuery
- func HTTPQueryFromTemplate(dt *pb.DataTemplate) *pb.HTTPQuery
- func HTTPResponseCode(m *pb.Method) (int32, error)
- func HTTPSuccessResponses(m *pb.Method) map[string]*pb.Data
- func InferMapsInMethod(method *pb.Method)
- func InferMapsInModel(model *pb.APISpec)
- func InstantiateOneOf(oneof *pb.OneOf, containerMeta *pb.DataMeta, factory OneOfInstantiator) (*pb.Data, error)
- func IsPrimitive(d *pb.Data) bool
- func IsPrimitiveList(d *pb.Data) bool
- func MergeOneOfMeta(containerMeta, optionMeta *pb.DataMeta) *pb.DataMeta
- func NewPrimitiveBool(v bool) *pb.Primitive
- func NewPrimitiveBytes(v []byte) *pb.Primitive
- func NewPrimitiveDouble(v float64) *pb.Primitive
- func NewPrimitiveFloat(v float32) *pb.Primitive
- func NewPrimitiveInt32(v int32) *pb.Primitive
- func NewPrimitiveInt64(v int64) *pb.Primitive
- func NewPrimitiveString(v string) *pb.Primitive
- func NewPrimitiveUint32(v uint32) *pb.Primitive
- func NewPrimitiveUint64(v uint64) *pb.Primitive
- func OneOf(data []*pb.Data, isConflict bool) (*pb.OneOf, error)
- func PropagateConstants(prefix []*pb.MethodTemplate, t *pb.MethodTemplate) error
- func RewriteHashKeys(spec *pb.APISpec) error
- func StructShouldBeMap(struc *pb.Struct) bool
- func TypeOfPrimitive(p *pb.Primitive) string
- func ValueFromPrimitive(p *pb.Primitive) (interface{}, error)
- type DataTypeID
- type ErrNoSuitableOneOf
- type InterpretStrings
- type IterMapTuple
- type MeldOptions
- type MeldedMethod
- type Melder
- type OneOfInstantiator
- type PrimitiveValue
- type RefMap
- type RefMapView
Constants ¶
const ( XAkitaCLIGitVersion = "x-akita-cli-git-version" XAkitaRequestID = "x-akita-request-id" XAkitaDogfood = "x-akita-dogfood" )
Variables ¶
var ( NoneData = &pb.Data{ Value: &pb.Data_Optional{ Optional: &pb.Optional{ Value: &pb.Optional_None{ None: &pb.None{}, }, }, }, } )
Functions ¶
func AddAnnotationToData ¶
func AddAnnotationToData(d *pb.Data, aa *pb.AkitaAnnotations)
func ContainsCLITraffic ¶
Returns true if the witness represents traffic from the CLI to our backend. These should get filtered out.
func EquivalentDataTemplates ¶
func EquivalentDataTemplates(sharedPrefix []*pb.MethodTemplate, dt1 *pb.DataTemplate, dt2 *pb.DataTemplate) (bool, error)
Given 2 DataTemplates that may contain references to Data in the common prefix, return whether the 2 DataTemplates are equivalent. Equivalence is defined as identical (modulo non-fixed values) after constant propagation, and there's a bijection between the non-fixed values. We can't use bijection to define equivalence over fixed values because each fixed value has a different meaning. For example, in enum{WRITER, READER}, it would be wrong to say WRITER == READER. Note we always treat bool primitives as "fixed", so bijection does not apply to bool values.
func ExtractValueFromTemplate ¶
Extracts a constant value from the given template. Does not recursively resolve references. Use in conjunction with PropagateConstants to handle recursive references, though the sequence generator should never generate recursive references in the first place since that is wasteful. Treats none value as an error.
func FlattenAlternatives ¶
Converts {"a": [1, 2], "b": [3]} to [{"a": 1, "b": 3}, {"a": 2, "b": 3}] Passing in a nil returns [nil].
func GetDataRef ¶
GetDataRef resolves a reference to the value being referenced. It treats references to a None value as an error. The caller may decide to ignore the error if the references are made by optional fields. TODO: Add unit tests for GetDataRef. Currently, unit test coverage comes from instantiator_test in worker, which is where we extract this piece of code from.
func HTTPBodyFromTemplate ¶
func HTTPBodyFromTemplate(dt *pb.DataTemplate) *pb.HTTPBody
func HTTPCookieFromData ¶
func HTTPCookieFromData(d *pb.Data) *pb.HTTPCookie
func HTTPCookieFromTemplate ¶
func HTTPCookieFromTemplate(dt *pb.DataTemplate) *pb.HTTPCookie
func HTTPHeaderFromData ¶
func HTTPHeaderFromData(d *pb.Data) *pb.HTTPHeader
func HTTPHeaderFromTemplate ¶
func HTTPHeaderFromTemplate(dt *pb.DataTemplate) *pb.HTTPHeader
func HTTPMetaFromMethod ¶
func HTTPMetaFromMethod(m *pb.Method) *pb.HTTPMethodMeta
func HTTPMultipartFromData ¶
func HTTPMultipartFromData(d *pb.Data) *pb.HTTPMultipart
func HTTPPathFromTemplate ¶
func HTTPPathFromTemplate(dt *pb.DataTemplate) *pb.HTTPPath
func HTTPQueryFromTemplate ¶
func HTTPQueryFromTemplate(dt *pb.DataTemplate) *pb.HTTPQuery
func HTTPResponseCode ¶
Extract the response code from the first response (meaningful for witnesses, which contain only at most one response.)
func HTTPSuccessResponses ¶
Extract responses returned under a successful status code
func InferMapsInMethod ¶
Check each non-map struct in method, and convert structs to maps if StructShouldBeMap is true.
func InferMapsInModel ¶
Check each non-map struct in model, and convert structs to maps if StructShouldBeMap is true.
func InstantiateOneOf ¶
func InstantiateOneOf(oneof *pb.OneOf, containerMeta *pb.DataMeta, factory OneOfInstantiator) (*pb.Data, error)
Given an OneOfInstantiator, this function feeds all oneof option specs to the factory and returns the "best" output. Currently, "best" is defined as having the most number of non-none fields. If a factory returns an error, its output is not considered. If all factories return error, this function returns ErrNoSuitableOneOf. containerMeta is the DataMeta of the Data object that contains the oneof.
Rationale for the scoring to pick the "best" instantiation: It's possible that multiple oneof options are valid for instantiation. For example, if the spec is:
oneof:
- struct{ "foo": optional bool } # option 1
- struct{ "bar": optional bool } # option 2
If the raw data is `{"foo": true}`, technically both options are valid specs for the raw data because option 2 can just treat the "bar" field as null, but option 1 is clearly better.
func IsPrimitive ¶
func IsPrimitiveList ¶
func MergeOneOfMeta ¶
Merges DataMeta from an oneof option with that of its containing Data object.
func NewPrimitiveBool ¶
func NewPrimitiveBytes ¶
func NewPrimitiveDouble ¶
func NewPrimitiveFloat ¶
func NewPrimitiveInt32 ¶
func NewPrimitiveInt64 ¶
func NewPrimitiveString ¶
func NewPrimitiveUint32 ¶
func NewPrimitiveUint64 ¶
func PropagateConstants ¶
func PropagateConstants(prefix []*pb.MethodTemplate, t *pb.MethodTemplate) error
Propagates constants within prefix that are referred to by references in t. Mutates t and may mutate elements in prefix that are references to constant values themselves.
func RewriteHashKeys ¶
Three maps in the IR use hashes of the values as keys (i.e. map[hash(v)] = v):
- Method.Args
- Method.Responses
- OneOf.Options
This method traverses the spec, recomputes the hash of each value, and updates the map.
func StructShouldBeMap ¶
Heuristically determines whether the given pb.Struct (assumed to not represent a map) should be a map.
func TypeOfPrimitive ¶
func ValueFromPrimitive ¶
Types ¶
type DataTypeID ¶
type DataTypeID string
Identifies the type of a protobuf Data message.
func DataToTypeID ¶
func DataToTypeID(d *pb.Data) DataTypeID
type ErrNoSuitableOneOf ¶
type ErrNoSuitableOneOf struct{}
func (ErrNoSuitableOneOf) Error ¶
func (e ErrNoSuitableOneOf) Error() string
type InterpretStrings ¶
type InterpretStrings bool
const ( // Indicates that strings should be interpreted as numbers or boolean values // wherever possible. INTERPRET_STRINGS InterpretStrings = true // Indicates that strings should remain strings. NO_INTERPRET_STRINGS InterpretStrings = false )
type IterMapTuple ¶
type IterMapTuple struct { Key interface{} Value interface{} }
func IterMapInOrder ¶
func IterMapInOrder(m interface{}) []IterMapTuple
type MeldOptions ¶
type MeldOptions struct { // Controls the maximum number of cookies that may be present in a meld // result. Any extra cookies are discarded. MaxNumCookies optionals.Optional[int] // Controls the maximum number of examples that are kept for each path // parameter. MaxNumPathParamExampleValues optionals.Optional[int] // Controls whether the examples kept for each path parameter are sampled at // random. KeepRandomPathParamExampleValues optionals.Optional[bool] }
type MeldedMethod ¶
type MeldedMethod interface { GetMethod() *pb.Method GetArgs() map[string]*pb.Data SetArgs(map[string]*pb.Data) GetResponses() map[string]*pb.Data SetResponses(map[string]*pb.Data) Has4xxOnly() bool SetHas4xxOnly(bool) Clone() MeldedMethod // Melds src into this instance, resolving conflicts using oneof. Assumes that this and src are for the same endpoint. // // Responses are always melded. But because they are likely to contain bogus data, requests that result in 4xx response codes are ignored where possible: // - If both src and this contain only 4xx responses, then requests are melded. // - Otherwise, if src contains only 4xx responses, then its requests are ignored. // - Otherwise, if this contains only 4xx responses, then its requests are replaced with requests from src. // - Otherwise, neither src nor this contain only 4xx responses, and requests are melded. Meld(src MeldedMethod, opts MeldOptions) error }
func NewMeldedMethod ¶
func NewMeldedMethod(method *pb.Method) MeldedMethod
type Melder ¶
type Melder struct {
// contains filtered or unexported fields
}
func NewMelder ¶
func NewMelder(opts MeldOptions) *Melder
type OneOfInstantiator ¶
A function that creates an instantiated Data from a Data spec.
type PrimitiveValue ¶
type PrimitiveValue interface { // Returns the zero value for this PrimitiveValue. Zero() PrimitiveValue // Returns the PrimitiveValue after obfuscating the original value while // keeping the type. For example, an int32 remains int32 after obfuscation // instead of becoming a []byte. Obfuscate() PrimitiveValue String() string ToProto() *pb.Primitive GoValue() interface{} // contains filtered or unexported methods }
Interface for values that our Primitive protobuf can represent.
func CategorizeString ¶
func CategorizeString(str string) PrimitiveValue
func PrimitiveValueFromProto ¶
func PrimitiveValueFromProto(p *pb.Primitive) (PrimitiveValue, error)
func ToPrimitiveValue ¶
func ToPrimitiveValue(v interface{}, interpretStrings InterpretStrings) (PrimitiveValue, error)
type RefMap ¶
type RefMap map[DataTypeID][]*pb.MethodDataRef
A read-only map that stores references to each method's argument and response values. We store MethodDataRef, but since the AkitaAnnotations inside each ref should come from the Data protobuf making the reference, AkitaAnnotations is filled in only in GetDataRefs
func (RefMap) GetDataRefs ¶
func (m RefMap) GetDataRefs(dID DataTypeID, aa *pb.AkitaAnnotations) []*pb.MethodDataRef
Create MethodDataRefs for all data of the given type in the args/responses of any previous method.
func (RefMap) HasRefs ¶
func (m RefMap) HasRefs(dID DataTypeID) bool
Given a method ID and a data type ID, returns whether there are references to the method's arguments or responses with the data type.
type RefMapView ¶
type RefMapView struct {
// contains filtered or unexported fields
}
A "view" into RefMap that keeps track of the prefix MethodTemplates in order to avoid returning references that are not useful. A reference is defined as "unuseful" if it:
- Refers to yet another reference (we will also return the other reference, so the new reference is redundant). RefMap may return references to references in response values, so we should filter these out.
- Refers to a skipped optional field
This cuts down on the number of possible sequences we can generate for a given data type.
func NewRefMapView ¶
func NewRefMapView(m RefMap, prefix []*pb.MethodTemplate) *RefMapView
func (*RefMapView) Copy ¶
func (v *RefMapView) Copy() *RefMapView
func (*RefMapView) GetDataRefs ¶
func (v *RefMapView) GetDataRefs(dID DataTypeID, aa *pb.AkitaAnnotations) []*pb.MethodDataRef
func (*RefMapView) GetFillableArgs ¶
func (v *RefMapView) GetFillableArgs(arg *pb.Data) []*pb.Data
Returns the set of data specs that can be filled using the data that's currently fillable. In most cases, if the arg is fillable, the returned result is identical. However, if the arg contains oneof fields, all fillable options are expanded and returned as separate results, where each result no longer has oneof fields.
func (*RefMapView) HasRefs ¶
func (v *RefMapView) HasRefs(dID DataTypeID) bool
Source Files
¶
- categorize.go
- classify.go
- const_prop.go
- constructors.go
- data_type_id.go
- equiv.go
- flatten.go
- hash_keys.go
- http.go
- infer_maps.go
- iter_map_in_order.go
- meld.go
- melded_method.go
- oneof.go
- primitive_type.go
- ref_map.go
- ref_map_view.go
- ref_resolver.go
- template_resolver.go
- value_from_data.go
- witness_filter.go