Skip to content

Commit bb8a758

Browse files
committed
Minor modifications to the existing analytics flow
1 parent ee08539 commit bb8a758

8 files changed

Lines changed: 62 additions & 36 deletions

File tree

gateway/gateway-controller/pkg/xds/translator.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ func (t *Translator) translateAPIConfig(cfg *models.StoredConfig) ([]*route.Rout
401401
for _, op := range apiData.Operations {
402402
// Use mainClusterName by default; path rewrite based on main upstream path
403403
r := t.createRoute(cfg.ID, apiData.DisplayName, apiData.Version, apiData.Context, string(op.Method), op.Path,
404-
mainClusterName, parsedMainURL.Path, effectiveMainVHost)
404+
mainClusterName, parsedMainURL.Path, effectiveMainVHost, cfg.Kind)
405405
mainRoutesList = append(mainRoutesList, r)
406406
}
407407
routesList = append(routesList, mainRoutesList...)
@@ -420,7 +420,7 @@ func (t *Translator) translateAPIConfig(cfg *models.StoredConfig) ([]*route.Rout
420420
for _, op := range apiData.Operations {
421421
// Use sbClusterName for sandbox upstream path
422422
r := t.createRoute(cfg.ID, apiData.DisplayName, apiData.Version, apiData.Context, string(op.Method), op.Path,
423-
sbClusterName, parsedSbURL.Path, effectiveSandboxVHost)
423+
sbClusterName, parsedSbURL.Path, effectiveSandboxVHost, cfg.Kind)
424424
sbRoutesList = append(sbRoutesList, r)
425425
}
426426
routesList = append(routesList, sbRoutesList...)
@@ -786,7 +786,7 @@ func (t *Translator) createRouteConfiguration(virtualHosts []*route.VirtualHost)
786786

787787
// createRoute creates a route for an operation
788788
func (t *Translator) createRoute(apiId, apiName, apiVersion, context, method, path, clusterName,
789-
upstreamPath string, vhost string) *route.Route {
789+
upstreamPath string, vhost string, apiKind string) *route.Route {
790790
// Resolve version placeholder in context
791791
context = strings.ReplaceAll(context, "$version", apiVersion)
792792

@@ -878,6 +878,7 @@ func (t *Translator) createRoute(apiId, apiName, apiVersion, context, method, pa
878878
"path": path,
879879
"method": method,
880880
"vhost": vhost,
881+
"api_kind": apiKind,
881882
}
882883
if metaStruct, err := structpb.NewStruct(metaMap); err == nil {
883884
r.Metadata = &core.Metadata{FilterMetadata: map[string]*structpb.Struct{

gateway/policy-engine/internal/analytics/analytics.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,19 @@ func (c *Analytics) prepareAnalyticEvent(logEntry *v3.HTTPAccessLogEntry) *dto.E
148148
slog.Debug(fmt.Sprintf("Filter metadata: %+v", sv))
149149
for key, value := range sv.Fields {
150150
if value != nil {
151-
keyValuePairsFromMetadata[key] = value.GetStringValue()
151+
if key == "analytics_data" {
152+
// Handle the analytics_data struct
153+
if analyticsStruct := value.GetStructValue(); analyticsStruct != nil {
154+
for analyticsKey, analyticsValue := range analyticsStruct.Fields {
155+
if analyticsValue != nil {
156+
keyValuePairsFromMetadata[analyticsKey] = analyticsValue.GetStringValue()
157+
}
158+
}
159+
}
160+
} else {
161+
// Handle regular string values
162+
keyValuePairsFromMetadata[key] = value.GetStringValue()
163+
}
152164
}
153165
}
154166
}

gateway/policy-engine/internal/analytics/constants.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ const (
9898
// APIVersionKey is the key for the API version.
9999
APIVersionKey = Wso2MetadataPrefix + "api-version"
100100
// APITypeKey is the key for the API type.
101-
APITypeKey = Wso2MetadataPrefix + "api-type"
101+
APITypeKey = Wso2MetadataPrefix + "api-kind"
102102
// APIUserNameKey is the key for the API user name.
103103
APIUserNameKey = Wso2MetadataPrefix + "username"
104104
// APIContextKey is the key for the API context.
@@ -141,8 +141,6 @@ const (
141141

142142
// ErrorCodeKey is the key for the error code.
143143
ErrorCodeKey = "ErrorCode"
144-
// ApkEnforcerReply is the key for the APK enforcer reply.
145-
ApkEnforcerReply = "apk-enforcer-reply"
146144
// RatelimitWso2OrgPrefix is the prefix for WSO2 organization rate limit.
147145
RatelimitWso2OrgPrefix = "customorg"
148146
// APIEnvironmentKey is the key for the API environment.

gateway/policy-engine/internal/analytics/publishers/moesif.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func (m *Moesif) Publish(event *dto.Event) {
108108
Verb: event.Operation.APIMethod,
109109
ApiVersion: &event.API.APIVersion,
110110
IpAddress: &event.UserIP,
111-
Headers: map[string]interface{}{ // TODO: Need to populate them dynamically
111+
Headers: map[string]interface{}{ // TODO (osura): Need to populate them dynamically
112112
"User-Agent": event.UserAgentHeader,
113113
"Content-Type": "application/json",
114114
},
@@ -119,7 +119,7 @@ func (m *Moesif) Publish(event *dto.Event) {
119119
respTime = event.RequestTimestamp.Add(time.Duration(event.Latencies.ResponseLatency) * time.Millisecond)
120120
}
121121

122-
rspHeaders := map[string]string{ //TODO: Need to populate them dynamically
122+
rspHeaders := map[string]string{ //TODO (osura): Need to populate them dynamically
123123
"Vary": "Accept-Encoding",
124124
"Pragma": "no-cache",
125125
"Expires": "-1",
@@ -133,7 +133,12 @@ func (m *Moesif) Publish(event *dto.Event) {
133133
Headers: rspHeaders,
134134
}
135135

136-
metadataMap := m.prepareMetadataMap(event.Properties)
136+
// Medatadata Map for the event
137+
metadataMap := make(map[string]interface{})
138+
m.addToMetadata("apiContext", event.API.APIContext, metadataMap)
139+
m.addToMetadata("apiName", event.API.APIName, metadataMap)
140+
m.addToMetadata("apiVersion", event.API.APIVersion, metadataMap)
141+
m.addToMetadata("apiType", event.API.APIType, metadataMap)
137142

138143
userID := anonymous
139144
eventModel := &models.EventModel{
@@ -148,13 +153,6 @@ func (m *Moesif) Publish(event *dto.Event) {
148153
}
149154

150155
// Map any additional metadata related to the event provided under properties
151-
func (m *Moesif) prepareMetadataMap(eventProps map[string]interface{}) map[string]interface{} {
152-
metadataMap := make(map[string]interface{})
153-
if aiMetadata, ok := eventProps["aiMetadata"]; ok {
154-
metadataMap["aiMetadata"] = aiMetadata
155-
}
156-
if aiTokenUsage, ok := eventProps["aiTokenUsage"]; ok {
157-
metadataMap["aiTokenUsage"] = aiTokenUsage
158-
}
159-
return metadataMap
156+
func (m *Moesif) addToMetadata(key, val string, metadataMap map[string]interface{}) {
157+
metadataMap[key] = val
160158
}

gateway/policy-engine/internal/kernel/analytics.go

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ import (
2626
"github.com/policy-engine/policy-engine/internal/constants"
2727
)
2828

29+
// Constants for analytics metadata
30+
const (
31+
Wso2MetadataPrefix = "x-wso2-"
32+
APIIDKey = Wso2MetadataPrefix + "api-id"
33+
APINameKey = Wso2MetadataPrefix + "api-name"
34+
APIVersionKey = Wso2MetadataPrefix + "api-version"
35+
APITypeKey = Wso2MetadataPrefix + "api-type"
36+
APIContextKey = Wso2MetadataPrefix + "api-context"
37+
OperationPathKey = Wso2MetadataPrefix + "operation-path"
38+
APIKindKey = Wso2MetadataPrefix + "api-kind"
39+
)
40+
2941
// buildAnalyticsStruct converts analytics metadata map to structpb.Struct
3042
// If execCtx is provided, adds system-level metadata (API name, version, etc.) to analytics_data.metadata
3143
func buildAnalyticsStruct(analyticsData map[string]any, execCtx *PolicyExecutionContext) (*structpb.Struct, error) {
@@ -43,31 +55,25 @@ func buildAnalyticsStruct(analyticsData map[string]any, execCtx *PolicyExecution
4355

4456
// Add system-level metadata if context is provided
4557
if execCtx != nil && execCtx.requestContext != nil && execCtx.requestContext.SharedContext != nil {
46-
metadata := make(map[string]interface{})
4758

4859
sharedCtx := execCtx.requestContext.SharedContext
4960
if sharedCtx.APIId != "" {
50-
metadata["api_id"] = sharedCtx.APIId
61+
fields[APIIDKey] = structpb.NewStringValue(sharedCtx.APIId)
5162
}
5263
if sharedCtx.APIName != "" {
53-
metadata["api_name"] = sharedCtx.APIName
64+
fields[APINameKey] = structpb.NewStringValue(sharedCtx.APIName)
5465
}
5566
if sharedCtx.APIVersion != "" {
56-
metadata["api_version"] = sharedCtx.APIVersion
67+
fields[APIVersionKey] = structpb.NewStringValue(sharedCtx.APIVersion)
5768
}
5869
if sharedCtx.APIContext != "" {
59-
metadata["api_context"] = sharedCtx.APIContext
70+
fields[APIContextKey] = structpb.NewStringValue(sharedCtx.APIContext)
6071
}
6172
if sharedCtx.OperationPath != "" {
62-
metadata["operation_path"] = sharedCtx.OperationPath
73+
fields[OperationPathKey] = structpb.NewStringValue(sharedCtx.OperationPath)
6374
}
64-
65-
if len(metadata) > 0 {
66-
metadataVal, err := structpb.NewValue(metadata)
67-
if err != nil {
68-
return nil, fmt.Errorf("failed to convert system metadata: %w", err)
69-
}
70-
fields["metadata"] = metadataVal
75+
if sharedCtx.APIKind != "" {
76+
fields[APIKindKey] = structpb.NewStringValue(sharedCtx.APIKind)
7177
}
7278
}
7379

@@ -99,16 +105,19 @@ func buildDynamicMetadata(analyticsStruct *structpb.Struct) *structpb.Struct {
99105
func extractMetadataFromRouteMetadata(routeMeta RouteMetadata) map[string]interface{} {
100106
metadata := make(map[string]interface{})
101107
if routeMeta.APIName != "" {
102-
metadata["api_name"] = routeMeta.APIName
108+
metadata[APINameKey] = routeMeta.APIName
103109
}
104110
if routeMeta.APIVersion != "" {
105-
metadata["api_version"] = routeMeta.APIVersion
111+
metadata[APIVersionKey] = routeMeta.APIVersion
106112
}
107113
if routeMeta.Context != "" {
108-
metadata["api_context"] = routeMeta.Context
114+
metadata[APIContextKey] = routeMeta.Context
109115
}
110116
if routeMeta.OperationPath != "" {
111-
metadata["operation_path"] = routeMeta.OperationPath
117+
metadata[OperationPathKey] = routeMeta.OperationPath
118+
}
119+
if routeMeta.APIKind != "" {
120+
metadata[APIKindKey] = routeMeta.APIKind
112121
}
113122
return metadata
114123
}

gateway/policy-engine/internal/kernel/execution_context.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ func (ec *PolicyExecutionContext) buildRequestContext(headers *extprocv3.HttpHea
332332
APIId: routeMetadata.APIId,
333333
APIName: routeMetadata.APIName,
334334
APIVersion: routeMetadata.APIVersion,
335+
APIKind: routeMetadata.APIKind,
335336
APIContext: routeMetadata.Context,
336337
OperationPath: routeMetadata.OperationPath,
337338
Metadata: make(map[string]interface{}),

gateway/policy-engine/internal/kernel/extproc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ type RouteMetadata struct {
324324
Context string
325325
OperationPath string
326326
Vhost string
327+
APIKind string
327328
}
328329

329330
// extractRouteMetadata extracts the route metadata from Envoy metadata
@@ -374,6 +375,9 @@ func (s *ExternalProcessorServer) extractRouteMetadata(req *extprocv3.Processing
374375
if vhostValue, ok := routeStruct.Fields["vhost"]; ok {
375376
metadata.Vhost = vhostValue.GetStringValue()
376377
}
378+
if originalAPIKindValue, ok := routeStruct.Fields["api_kind"]; ok {
379+
metadata.APIKind = originalAPIKindValue.GetStringValue()
380+
}
377381
}
378382
}
379383
}

sdk/gateway/policy/v1alpha/context.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ type SharedContext struct {
3838
// APIVersion is the version of the API (e.g., "v1.0.0")
3939
APIVersion string
4040

41+
// APIKind is the type of the API
42+
APIKind string
43+
4144
// APIContext is the base context path of the API (e.g., "/petstore")
4245
// This is the base path without the version
4346
APIContext string

0 commit comments

Comments
 (0)