Skip to content

Commit

Permalink
updates found while testing
Browse files Browse the repository at this point in the history
  • Loading branch information
jcollins-axway committed Nov 1, 2024
1 parent 918e936 commit 6e39240
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 25 deletions.
60 changes: 47 additions & 13 deletions pkg/agent/handler/accessrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package handler

import (
"context"
"encoding/json"
"fmt"

agentcache "github.com/Axway/agent-sdk/pkg/agent/cache"
"github.com/Axway/agent-sdk/pkg/amplify/agent/customunits"
apiv1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1"
"github.com/Axway/agent-sdk/pkg/apic/apiserver/models/catalog/v1"
management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1"
defs "github.com/Axway/agent-sdk/pkg/apic/definitions"
prov "github.com/Axway/agent-sdk/pkg/apic/provisioning"
Expand Down Expand Up @@ -138,10 +140,10 @@ func (h *accessRequestHandler) onPending(ctx context.Context, ar *management.Acc
data := map[string]interface{}{}
status, accessData := h.prov.AccessRequestProvision(req)

if status.GetStatus() == prov.Success {
if status.GetStatus() == prov.Success && len(ar.Spec.AdditionalQuotas) > 0 {
metricServicesConfigs := h.metricServicesConfig
// Build quota info
quotaInfo, err := h.buildQuotaInfo(ctx, ar)
quotaInfo, err := h.buildQuotaInfo(ctx, ar, app)
if err != nil {
log.WithError(err).Errorf("error building quota info")
h.onError(ctx, ar, err)
Expand All @@ -153,7 +155,7 @@ func (h *accessRequestHandler) onPending(ctx context.Context, ar *management.Acc
factory := customunit.NewQuotaEnforcementClientFactory(config.URL, quotaInfo)
client, _ := factory(ctx)
response, err := client.QuotaEnforcementInfo()
if err == nil {
if err != nil {
// if error from QE and reject on fail, we return the error back to the central
if response.Error != "" && config.RejectOnFailEnabled() {
errMessage = errMessage + fmt.Sprintf("TODO: message: %s", err.Error())
Expand Down Expand Up @@ -297,36 +299,68 @@ func (h *accessRequestHandler) getARD(ctx context.Context, ar *management.Access
return ard, err
}

func (h *accessRequestHandler) buildQuotaInfo(ctx context.Context, ar *management.AccessRequest) (*customunits.QuotaInfo, error) {
// Get service instance from access request to fetch the api service
type reference struct {
Kind string `json:"kind"`
Name string `json:"name"`
Unit string `json:"unit"`
}

func (h *accessRequestHandler) getQuotaInfo(ar *management.AccessRequest) (string, int) {
index := 0
if len(ar.Spec.AdditionalQuotas) < index+1 {
return "", 0
}

q := ar.Spec.AdditionalQuotas[index]
for _, r := range ar.References {
d, _ := json.Marshal(r)
ref := &reference{}
json.Unmarshal(d, ref)
if ref.Kind == catalog.QuotaGVK().Kind && ref.Name == q.Name {
return ref.Unit, int(q.Limit)
}
}
return "", 0
}

func (h *accessRequestHandler) buildQuotaInfo(ctx context.Context, ar *management.AccessRequest, app *management.ManagedApplication) (*customunits.QuotaInfo, error) {
unitRef, count := h.getQuotaInfo(ar)
if unitRef == "" {
return nil, nil
}

instance, err := h.getServiceInstance(ctx, ar)
if err != nil {
return nil, err
}

// Get service instance from access request to fetch the api service
serviceRef := instance.GetReferenceByGVK(management.APIServiceGVK())
serviceID := serviceRef.ID
service := h.cache.GetAPIServiceWithAPIID(serviceID)
extAPIID, err := util.GetAgentDetailsValue(service, defs.AttrExternalAPIID)
service := h.cache.GetAPIServiceWithName(serviceRef.Name)
if service == nil {
return nil, fmt.Errorf("could not find service connected to quota")
}
extAPIID, err := util.GetAgentDetailsValue(instance, defs.AttrExternalAPIID)
if err != nil {
return nil, err
}
// Get app info from the access request
appRef := instance.GetReferenceByGVK(management.ManagedApplicationGVK())
appName := appRef.Name
app := h.cache.GetManagedApplicationByName(appName)

q := &customunits.QuotaInfo{
ApiInfo: &customunits.APIInfo{
ServiceDetails: util.GetAgentDetailStrings(service),
ServiceName: service.Name,
ServiceID: serviceID,
ServiceID: service.Metadata.ID,
ExternalAPIID: extAPIID,
},
AppInfo: &customunits.AppInfo{
AppDetails: util.GetAgentDetailStrings(app),
AppName: app.Name,
AppID: app.Metadata.ID,
},
Quota: &customunits.Quota{
Count: int64(count),
Unit: unitRef,
},
}

return q, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type AccessRequestSpec struct {
// The name of an ManagedApplication resource that groups set of credentials.
ManagedApplication string `json:"managedApplication"`
// The value that matches the AccessRequestDefinition schema linked to the referenced APIServiceInstance. (management.v1alpha1.AccessRequest)
Data map[string]interface{} `json:"data"`
Quota *AccessRequestSpecQuota `json:"quota,omitempty"`
Data map[string]interface{} `json:"data"`
Quota *AccessRequestSpecQuota `json:"quota,omitempty"`
AdditionalQuotas []AccessRequestSpecAdditionalQuotas `json:"additionalQuotas,omitempty"`
}
6 changes: 6 additions & 0 deletions pkg/config/agentfeaturesconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func AddAgentFeaturesConfigProperties(props properties.Properties) {
props.AddBoolProperty(pathVersionChecker, true, "Controls whether the agent SDK version checker will be enabled or not")
props.AddBoolProperty(pathPersistCache, true, "Controls whether the agent SDK will persist agent cache or not")
props.AddBoolProperty(pathAgentStatusUpdates, true, "Controls whether the agent should manage the status update or not")
addMetricServicesProperties(props)
addExternalIDPProperties(props)
}

Expand All @@ -114,6 +115,11 @@ func ParseAgentFeaturesConfig(props properties.Properties) (AgentFeaturesConfig,
PersistCache: props.BoolPropertyValueOrTrue(pathPersistCache),
AgentStatusUpdates: props.BoolPropertyValueOrTrue(pathAgentStatusUpdates),
}
metricSvsCfgs, err := parseMetricServicesConfig(props)
if err != nil {
return nil, err
}
cfg.MetricServicesConfigs = metricSvsCfgs
externalIDPCfg, err := parseExternalIDPConfig(props)
if err != nil {
return nil, err
Expand Down
64 changes: 58 additions & 6 deletions pkg/config/metricserviceconfig.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
package config

import (
"encoding/json"
"fmt"
"net/url"
"strconv"

"github.com/Axway/agent-sdk/pkg/cmd/properties"
"github.com/Axway/agent-sdk/pkg/util/exception"
)

const (
pathMetricServiceEnable = "agentFeatures.metricServices.enable"
pathMetricServiceURL = "agentFeatures.metricServices.url"
pathRejectOnFail = "agentFeatures.metricServices.rejectOnFail"
pathMetricServices = "agentFeatures.metricServices"
pathMetricServiceEnable = "enable"
pathMetricServiceURL = "url"
pathRejectOnFail = "rejectOnFail"
)

var metricServiceProps = []string{
pathMetricServiceEnable,
pathMetricServiceURL,
pathRejectOnFail,
}

func addMetricServicesProperties(props properties.Properties) {
props.AddObjectSliceProperty(pathMetricServices, metricServiceProps)
}

type MetricServiceConfig interface {
MetricServiceEnabled() bool
GetMetricServiceURL() string
Expand All @@ -21,9 +36,15 @@ type MetricServiceConfig interface {

type MetricServiceConfiguration struct {
MetricServiceConfig
Enable bool `config:"enable"` // set to true to have the sdk initiate the connection to the custom metric service
URL string `config:"url"` // set the url that the agent will connect to the metric service on
RejectOnFail bool `config:"rejectOnFail"` // set to true to reject the access request if the quota enforcement call fails
Enable bool // set to true to have the sdk initiate the connection to the custom metric service
URL string // set the url that the agent will connect to the metric service on
RejectOnFail bool // set to true to reject the access request if the quota enforcement call fails
}

type metricsvcconfig struct {
Enable string `json:"enable"`
URL string `json:"url"`
RejectOnFail string `json:"rejectOnFail"`
}

func (a *MetricServiceConfiguration) validate() {
Expand All @@ -47,3 +68,34 @@ func (c *MetricServiceConfiguration) GetMetricServiceURL() string {
func (c *MetricServiceConfiguration) RejectOnFailEnabled() bool {
return c.RejectOnFail
}

func parseMetricServicesConfig(props properties.Properties) ([]MetricServiceConfiguration, error) {
svcCfgList := props.ObjectSlicePropertyValue(pathMetricServices)

cfgs := []MetricServiceConfiguration{}

for _, svcCfgProps := range svcCfgList {
svcCfg := metricsvcconfig{}

buf, _ := json.Marshal(svcCfgProps)
err := json.Unmarshal(buf, &svcCfg)
if err != nil {
return nil, fmt.Errorf("error parsing metrics service configuration, %s", err)
}
cfgs = append(cfgs, MetricServiceConfiguration{
Enable: parseBool(svcCfg.Enable),
URL: svcCfg.URL,
RejectOnFail: parseBool(svcCfg.RejectOnFail),
})
}

return cfgs, nil
}

func parseBool(str string) bool {
v, err := strconv.ParseBool(str)
if err != nil {
return false
}
return v
}
2 changes: 1 addition & 1 deletion pkg/customunit/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ func NewCustomMetricReportingClientFactory(url string, agentCache cache.Manager)
dialOpts: []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
},
timer: time.NewTimer(time.Hour),
}

for _, o := range opts {
Expand Down Expand Up @@ -184,7 +185,6 @@ func (c *customUnitMetricReportingClient) processMetrics() {
}
c.reportMetrics(metricReport)
}

}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/transaction/metric/cachestorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (c *cacheStorage) loadMetrics(storageCache cache.Cache) {
continue
}

c.collector.AddCustomMetricDetail(CustomMetricDetail{
c.collector.AddCustomMetricDetail(models.CustomMetricDetail{
APIDetails: apiDetails,
AppDetails: appDetails,
UnitDetails: models.Unit{
Expand Down
2 changes: 1 addition & 1 deletion pkg/transaction/metric/metricscollector.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ func (c *collector) createMetric(detail transactionContext) *centralMetric {
API: c.createAPIDetail(detail.APIDetails),
AssetResource: c.getAssetResource(accessRequest),
ProductPlan: c.getProductPlan(accessRequest),
Observation: &ObservationDetails{
Observation: &models.ObservationDetails{
Start: now().Unix(),
},
EventID: uuid.NewString(),
Expand Down
2 changes: 1 addition & 1 deletion pkg/transaction/metric/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
func centralMetricFromAPIMetric(in *APIMetric) *centralMetric {
out := &centralMetric{
EventID: in.EventID,
Observation: &ObservationDetails{
Observation: &models.ObservationDetails{
Start: in.Observation.Start,
},
}
Expand Down

0 comments on commit 6e39240

Please sign in to comment.