discovery

package
v0.5.2-beta01 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 6, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const (
	BinResponseShapeUnsafe = "response-shape-unsafe"
	BinObjectKeyUnroutable = "objectKey-unroutable"
	BinEmptyResponseUnsafe = "empty-response-unsafe"
	BinMediaTypeMismatch   = "media-type-mismatch"
	BinMissingSemantics    = "missing-semantics"
)

Warning classification bins for static analysis.

View Source
const (
	BinRequestParamUnroutable  = "request-param-unroutable"
	BinRefResolutionFailed     = "ref-resolution-failed"
	BinSQLVerbCoverage         = "sql-verb-coverage"
	BinServerURLInvalid        = "server-url-invalid"
	BinPaginationIncomplete    = "pagination-incomplete"
	BinTransformSchemaMismatch = "transform-schema-mismatch"
)

Analysis bins for new static checks.

View Source
const BinCrossResourceInconsistency = "cross-resource-inconsistent"

BinCrossResourceInconsistency is the bin for cross-resource consistency issues.

Variables

This section is empty.

Functions

func ClassifyWarnings

func ClassifyWarnings(warnings []string) map[string][]string

ClassifyWarnings parses tagged warning strings and groups them by bin (legacy).

func FormatFindingJSON

func FormatFindingJSON(f AnalysisFinding) string

FormatFindingJSON returns a single JSONL line for a structured finding.

func FormatLogEntryJSON

func FormatLogEntryJSON(level string, message string) string

FormatLogEntryJSON returns a single JSONL line for an analysis event.

func FormatSummaryJSON

func FormatSummaryJSON(legacyErrors []error, legacyWarnings []string, affirmatives []string, findings []AnalysisFinding) string

FormatSummaryJSON returns a JSON summary from structured findings.

func FormatWarningSummary

func FormatWarningSummary(warnings []string) string

FormatWarningSummary returns a human-readable summary (legacy, kept for reference).

func GenerateExpectedResponse

func GenerateExpectedResponse(postTransform string, selectItemsKey string) string

GenerateExpectedResponse extracts the items array from the post-transform JSON using the selectItemsKey, and wraps it as a JSON array — matching `stackql exec -o json` output. Returns empty string if selectItemsKey is absent (expected response cannot be reliably predicted).

func GenerateMockRoute

func GenerateMockRoute(
	providerName string,
	serviceName string,
	resourceName string,
	methodName string,
	httpVerb string,
	operationName string,
	parameterizedPath string,
	responseMediaType string,
	requiredParams map[string]anysdk.Addressable,
) string

func GenerateSampleResponse

func GenerateSampleResponse(schema anysdk.Schema, mediaType string) string

GenerateSampleResponse walks a response schema and produces a sample response body as a JSON string. This is used for empirical template testing.

func GenerateSampleXMLResponse

func GenerateSampleXMLResponse(schema anysdk.Schema, rootElement string) string

GenerateSampleXMLResponse produces a minimal XML sample from the schema. If the schema is an object with properties, each top-level property becomes a root XML element — matching real API responses that don't wrap in an artificial <Response> envelope.

func GenerateStackQLQuery

func GenerateStackQLQuery(
	providerName string,
	serviceName string,
	resourceName string,
	sqlVerb string,
	requiredParams map[string]anysdk.Addressable,
	requestBodyAttrs map[string]anysdk.Addressable,
) string

GenerateStackQLQuery produces a StackQL SQL query that exercises the given method. It partitions parameters by location: server/path/query params go in WHERE, requestBody params go in column/value lists for INSERT or SET for UPDATE.

func InferMediaType

func InferMediaType(body string, fallback string) string

InferMediaType determines the content type from the response body content. If the body starts with '<', it's XML; otherwise fall back to the provided default.

func MockResponseVarName

func MockResponseVarName(providerName, serviceName, resourceName, methodName string) string

MockResponseVarName returns the Python variable name for the mock response body constant.

func WriteExpectationFiles

func WriteExpectationFiles(findings []AnalysisFinding, outputDir string) error

WriteExpectationFiles writes individual expected response files for each finding that has an expected_response. Each file is a plain text file containing the expected JSON output from `stackql exec -o json`.

func WriteMockFiles

func WriteMockFiles(findings []AnalysisFinding, outputDir string) error

WriteMockFiles writes individual Python mock files for each finding that has a mock_route and sample_response. Each file is a standalone Flask app that can be run directly. WriteMockFiles writes individual Python mock files and a manifest mapping each filename to its provider/service/resource/method components.

func WriteQueryFiles

func WriteQueryFiles(findings []AnalysisFinding, outputDir string) error

WriteQueryFiles writes individual StackQL query files for each finding that has a stackql_query. Each file is a plain text file containing the query.

Types

type AnalysisBin

type AnalysisBin struct {
	Count    int      `json:"count"`
	Errors   []string `json:"errors,omitempty"`
	Warnings []string `json:"warnings,omitempty"`
}

AnalysisBin holds the items for a single classification bin.

type AnalysisContext

type AnalysisContext struct {
	Provider string
	Service  string
	Resource string
	Method   string
}

AnalysisContext carries the hierarchy context for producing findings.

func (AnalysisContext) NewError

func (ctx AnalysisContext) NewError(bin string, message string) AnalysisFinding

func (AnalysisContext) NewInfo

func (ctx AnalysisContext) NewInfo(message string) AnalysisFinding

func (AnalysisContext) NewWarning

func (ctx AnalysisContext) NewWarning(bin string, message string) AnalysisFinding

type AnalysisFinding

type AnalysisFinding struct {
	Level            string                               `json:"level"`
	Bin              string                               `json:"bin,omitempty"`
	Provider         string                               `json:"provider,omitempty"`
	Service          string                               `json:"service,omitempty"`
	Resource         string                               `json:"resource,omitempty"`
	Method           string                               `json:"method,omitempty"`
	Message          string                               `json:"message"`
	PriorTemplate    string                               `json:"prior_template,omitempty"`
	FixedTemplate    string                               `json:"fixed_template,omitempty"`
	EmpiricalTests   *stream_transform.EmpiricalTestSuite `json:"empirical_tests,omitempty"`
	SampleResponse   *SampleResponsePair                  `json:"sample_response,omitempty"`
	MockRoute        string                               `json:"mock_route,omitempty"`
	StackQLQuery     string                               `json:"stackql_query,omitempty"`
	ExpectedResponse string                               `json:"expected_response,omitempty"`
}

AnalysisFinding is a structured finding from static analysis. It carries the full provider/service/resource/method hierarchy.

func (AnalysisFinding) Error

func (f AnalysisFinding) Error() string

func (AnalysisFinding) String

func (f AnalysisFinding) String() string

type AnalysisSummary

type AnalysisSummary struct {
	TotalOK       int                       `json:"total_ok"`
	TotalWarnings int                       `json:"total_warnings"`
	TotalErrors   int                       `json:"total_errors"`
	Scores        *ScoreMetrics             `json:"scores,omitempty"`
	Bins          map[string]AnalysisBin    `json:"bins"`
	Services      map[string]ServiceSummary `json:"services"`
	Errors        []string                  `json:"errors,omitempty"`
}

AnalysisSummary is the JSON-serialisable top-level output of static analysis.

type AnalyzedFullHierarchy

type AnalyzedFullHierarchy interface {
	AnalyzedPartialHierarchy
	GetMethod() anysdk.StandardOperationStore
}

type AnalyzedPartialHierarchy

type AnalyzedPartialHierarchy interface {
	GetProvider() anysdk.Provider
	GetService() anysdk.ProviderService
	GetResource() anysdk.Resource
	GetMethods() anysdk.Methods
	GetRegistryAPI() anysdk.RegistryAPI
}

type AnalyzerCfg

type AnalyzerCfg interface {
	GetProtocolType() string
	GetDocRoot() string
	GetRegistryRootDir() string
	GetSchemaRootDir() string
	GetProviderStr() string
	GetRootURL() string
	IsProviderServicesMustExpand() bool
	IsVerbose() bool
	SetIsVerbose(bool)
	SetIsProviderServicesMustExpand(bool)
	IsSkipSchemaValidation() bool
}

func NewAnalyzerCfg

func NewAnalyzerCfg(
	protocolType string,
	registryRootDir string,
	docRoot string,
	schemaDir string,
	skipSchemaValidation bool,
) AnalyzerCfg

type BasicDiscoveryAdapter

type BasicDiscoveryAdapter struct {
	// contains filtered or unexported fields
}

func (*BasicDiscoveryAdapter) GetProvider

func (adp *BasicDiscoveryAdapter) GetProvider(providerKey string) (anysdk.Provider, error)

func (*BasicDiscoveryAdapter) GetResourcesMap

func (adp *BasicDiscoveryAdapter) GetResourcesMap(
	prov anysdk.Provider,
	serviceKey string,
) (map[string]anysdk.Resource, error)

func (*BasicDiscoveryAdapter) GetServiceHandle

func (adp *BasicDiscoveryAdapter) GetServiceHandle(
	prov anysdk.Provider,
	serviceKey string,
) (anysdk.ProviderService, error)

func (*BasicDiscoveryAdapter) GetServiceHandlesMap

func (adp *BasicDiscoveryAdapter) GetServiceHandlesMap(
	prov anysdk.Provider,
) (map[string]anysdk.ProviderService, error)

func (*BasicDiscoveryAdapter) GetServiceShard

func (adp *BasicDiscoveryAdapter) GetServiceShard(
	prov anysdk.Provider,
	serviceKey,
	resourceKey string,
) (anysdk.Service, error)

func (*BasicDiscoveryAdapter) PersistStaticExternalSQLDataSource

func (adp *BasicDiscoveryAdapter) PersistStaticExternalSQLDataSource(prov anysdk.Provider) error

type FindingsAware

type FindingsAware interface {
	GetFindings() []AnalysisFinding
}

FindingsAware is an optional interface for analyzers that produce structured findings.

type IDiscoveryAdapter

type IDiscoveryAdapter interface {
	GetResourcesMap(prov anysdk.Provider, serviceKey string) (map[string]anysdk.Resource, error)
	GetServiceShard(prov anysdk.Provider, serviceKey, resourceKey string) (anysdk.Service, error)
	GetServiceHandlesMap(prov anysdk.Provider) (map[string]anysdk.ProviderService, error)
	GetServiceHandle(prov anysdk.Provider, serviceKey string) (anysdk.ProviderService, error)
	GetProvider(providerKey string) (anysdk.Provider, error)
	PersistStaticExternalSQLDataSource(prov anysdk.Provider) error
	// contains filtered or unexported methods
}

func NewBasicDiscoveryAdapter

func NewBasicDiscoveryAdapter(
	alias string,
	apiDiscoveryDocURL string,
	discoveryStore IDiscoveryStore,
	runtimeCtx *dto.RuntimeCtx,
	registry anysdk.RegistryAPI,
	persistenceSystem persistence.PersistenceSystem,
) IDiscoveryAdapter

type IDiscoveryStore

type IDiscoveryStore interface {
	ProcessProviderDiscoveryDoc(string, string) (anysdk.Provider, error)

	PersistServiceShard(anysdk.Provider, anysdk.ProviderService, string) (anysdk.Service, error)
	// contains filtered or unexported methods
}

func NewTTLDiscoveryStore

func NewTTLDiscoveryStore(
	persistenceSystem persistence.PersistenceSystem,
	registry anysdk.RegistryAPI,
	runtimeCtx dto.RuntimeCtx,
) IDiscoveryStore

type Interrogator

type Interrogator interface {
	GetProviderServices() ([]string, error)
}

func NewInterrogator

func NewInterrogator(providerRootDoc, registryRootDir string) Interrogator

type MethodAggregateStaticAnalyzer

type MethodAggregateStaticAnalyzer interface {
	StaticAnalyzer
	GetFullHierarchy() (AnalyzedFullHierarchy, bool)
}

type ProviderServiceResourceAnalyzer

type ProviderServiceResourceAnalyzer interface {
	StaticAnalyzer
	GetResources() map[string]anysdk.Resource
	GetServiceFragments() map[string]anysdk.Service
	GetProvider() (anysdk.Provider, bool)
	GetProviderService() (anysdk.ProviderService, bool)
}

func NewProviderServiceResourceAnalyzer

func NewProviderServiceResourceAnalyzer(
	cfg AnalyzerCfg,
	discoveryAdapter IDiscoveryAdapter,
	discoveryStore IDiscoveryStore,
	provider anysdk.Provider,
	providerService anysdk.ProviderService,
	resourceKey string,
	registryAPI anysdk.RegistryAPI,
) ProviderServiceResourceAnalyzer

type ResourceAggregateStaticAnalyzer

type ResourceAggregateStaticAnalyzer interface {
	StaticAnalyzer
	GetPartialHierarchy() (AnalyzedPartialHierarchy, bool)
	FindMethodByVerbAndParameters(sqlVerb string, params map[string]any) (anysdk.StandardOperationStore, map[string]any, bool)
}

type SampleResponsePair

type SampleResponsePair struct {
	VarName       string `json:"var_name,omitempty"`
	PreTransform  string `json:"pre_transform"`
	PostTransform string `json:"post_transform"`
}

SampleResponsePair holds pre-transform and post-transform sample responses.

func GenerateSampleResponsePair

func GenerateSampleResponsePair(
	rawSchema anysdk.Schema,
	rawMediaType string,
	overrideSchema anysdk.Schema,
	overrideMediaType string,
) *SampleResponsePair

GenerateSampleResponsePair produces both samples from the raw and override schemas. rawSchema is the base API response schema (pre-transform), rawMediaType its media type. overrideSchema is the post-transform schema (may be nil if no transform). overrideMediaType is the post-transform media type (may be empty).

type ScoreMetrics

type ScoreMetrics struct {
	TotalMethods          int     `json:"total_methods"`
	MethodsWithMocks      int     `json:"methods_with_mocks"`
	MethodsWithTransforms int     `json:"methods_with_transforms"`
	MethodsClean          int     `json:"methods_clean"`
	ErrorRate             float64 `json:"error_rate"`
	WarningRate           float64 `json:"warning_rate"`
	CleanRate             float64 `json:"clean_rate"`
	MockCoverage          float64 `json:"mock_coverage"`
}

ScoreMetrics provides aggregate pass rates and health scores.

type ServiceSummary

type ServiceSummary struct {
	ErrorCount   int `json:"error_count"`
	WarningCount int `json:"warning_count"`
}

ServiceSummary aggregates error and warning counts per service.

type StaticAnalyzer

type StaticAnalyzer interface {
	Analyze() error
	GetErrors() []error
	GetWarnings() []string
	GetAffirmatives() []string
	GetRegistryAPI() (anysdk.RegistryAPI, bool)
}

func NewServiceLevelStaticAnalyzer

func NewServiceLevelStaticAnalyzer(
	cfg AnalyzerCfg,
	discoveryAdapter IDiscoveryAdapter,
	discoveryStore IDiscoveryStore,
	provider anysdk.Provider,
	providerService anysdk.ProviderService,
	providerServiceKey string,
	registryAPI anysdk.RegistryAPI,
) StaticAnalyzer

func NewStaticAnalyzer

func NewStaticAnalyzer(
	analysisCfg AnalyzerCfg,
	persistenceSystem persistence.PersistenceSystem,
	registryAPI anysdk.RegistryAPI,
	rtCtx dto.RuntimeCtx,
) (StaticAnalyzer, error)

type StaticAnalyzerFactory

type StaticAnalyzerFactory interface {
	CreateStaticAnalyzer(
		providerURL string,
	) (StaticAnalyzer, error)
	CreateProviderServiceLevelStaticAnalyzer(
		providerURL string,
		serviceName string,
	) (ProviderServiceResourceAnalyzer, error)
	CreateServiceLevelStaticAnalyzer(
		providerURL string,
		serviceName string,
	) (StaticAnalyzer, error)
	CreateMethodAggregateStaticAnalyzer(
		providerURL string,
		providerName string,
		serviceName string,
		resourceName string,
		methodSelectorName string,
		isFuzzy bool,
	) (MethodAggregateStaticAnalyzer, error)
	CreateResourceAggregateStaticAnalyzer(
		providerURL string,
		providerName string,
		serviceName string,
		resourceName string,
	) (ResourceAggregateStaticAnalyzer, error)
}

type StaticAnalyzerFactoryFactory

type StaticAnalyzerFactoryFactory interface {
	CreateNaiveSQLiteStaticAnalyzerFactory(
		registryAPI anysdk.RegistryAPI,
		rtCtx dto.RuntimeCtx,
	) (StaticAnalyzerFactory, error)
	CreateStaticAnalyzerFactoryFromPersistenceSystem(
		registryAPI anysdk.RegistryAPI,
		rtCtx dto.RuntimeCtx,
		persistenceSystem persistence.PersistenceSystem,
	) (StaticAnalyzerFactory, error)
}

func NewStandardStaticAnalyzerFactoryFactory

func NewStandardStaticAnalyzerFactoryFactory() StaticAnalyzerFactoryFactory

type TTLDiscoveryStore

type TTLDiscoveryStore struct {
	// contains filtered or unexported fields
}

func (*TTLDiscoveryStore) PersistServiceShard

func (store *TTLDiscoveryStore) PersistServiceShard(
	pr anysdk.Provider,
	serviceHandle anysdk.ProviderService,
	resourceKey string,
) (anysdk.Service, error)

TODO: this is the obvious place to add namespace analysis and persistence.

Therefore, need to ensure it happens only after all dependents and prior to any namespace usage.

func (*TTLDiscoveryStore) ProcessProviderDiscoveryDoc

func (store *TTLDiscoveryStore) ProcessProviderDiscoveryDoc(url string, alias string) (anysdk.Provider, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL