From 5dcd5e848c98a60c5711dd27f29bd3a2b27c4841 Mon Sep 17 00:00:00 2001
From: Yordan Kinkov <yordan.kinkov@vereign.com>
Date: Fri, 7 Oct 2022 14:28:26 +0300
Subject: [PATCH] Add cache TTL attribute in export configuration

---
 internal/clients/policy/client.go             |  12 +++++--
 .../infohub/infohubfakes/fake_credentials.go  |   2 +-
 .../infohub/infohubfakes/fake_policy.go       |  18 +++++-----
 .../infohub/infohubfakes/fake_signer.go       |   2 +-
 internal/service/infohub/service.go           |   4 +--
 internal/service/infohub/service_test.go      |  31 ++++++++++++++++--
 internal/storage/storage.go                   |   1 +
 .../tsa/golib/ptr/ptr.go                      | Bin 0 -> 1629 bytes
 vendor/modules.txt                            | Bin 16460 -> 16532 bytes
 9 files changed, 54 insertions(+), 16 deletions(-)
 create mode 100644 vendor/gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/ptr/ptr.go

diff --git a/internal/clients/policy/client.go b/internal/clients/policy/client.go
index 3231f36..c6b664a 100644
--- a/internal/clients/policy/client.go
+++ b/internal/clients/policy/client.go
@@ -8,11 +8,15 @@ import (
 	"io"
 	"net/http"
 	"net/url"
+	"strconv"
 
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/errors"
 )
 
-const headerEvaluationID = "x-evaluation-id"
+const (
+	headerEvaluationID = "x-evaluation-id"
+	headerCacheTTL     = "x-cache-ttl"
+)
 
 type Client struct {
 	addr       string
@@ -36,7 +40,7 @@ func New(addr string, opts ...ClientOption) *Client {
 // The policy is expected as a string path uniquely identifying the
 // policy that has to be evaluated. For example, with policy = `gaiax/didResolve/1.0`,
 // the client will do HTTP request to http://policyhost/policy/gaiax/didResolve/1.0/evaluation.
-func (c *Client) Evaluate(ctx context.Context, policy string, data interface{}, evaluationID string) ([]byte, error) {
+func (c *Client) Evaluate(ctx context.Context, policy string, data interface{}, evaluationID string, ttl *int) ([]byte, error) {
 	uri := c.addr + "/policy/" + policy + "/evaluation"
 	policyURL, err := url.ParseRequestURI(uri)
 	if err != nil {
@@ -57,6 +61,10 @@ func (c *Client) Evaluate(ctx context.Context, policy string, data interface{},
 		req.Header.Set(headerEvaluationID, evaluationID)
 	}
 
+	if ttl != nil {
+		req.Header.Set(headerCacheTTL, strconv.Itoa(*ttl))
+	}
+
 	resp, err := c.httpClient.Do(req.WithContext(ctx))
 	if err != nil {
 		return nil, err
diff --git a/internal/service/infohub/infohubfakes/fake_credentials.go b/internal/service/infohub/infohubfakes/fake_credentials.go
index d06091d..a66c248 100644
--- a/internal/service/infohub/infohubfakes/fake_credentials.go
+++ b/internal/service/infohub/infohubfakes/fake_credentials.go
@@ -4,8 +4,8 @@ package infohubfakes
 import (
 	"sync"
 
-	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/internal/service/infohub"
 	"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
+	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/internal/service/infohub"
 )
 
 type FakeCredentials struct {
diff --git a/internal/service/infohub/infohubfakes/fake_policy.go b/internal/service/infohub/infohubfakes/fake_policy.go
index 916504b..cdd4e13 100644
--- a/internal/service/infohub/infohubfakes/fake_policy.go
+++ b/internal/service/infohub/infohubfakes/fake_policy.go
@@ -9,13 +9,14 @@ import (
 )
 
 type FakePolicy struct {
-	EvaluateStub        func(context.Context, string, interface{}, string) ([]byte, error)
+	EvaluateStub        func(context.Context, string, interface{}, string, *int) ([]byte, error)
 	evaluateMutex       sync.RWMutex
 	evaluateArgsForCall []struct {
 		arg1 context.Context
 		arg2 string
 		arg3 interface{}
 		arg4 string
+		arg5 *int
 	}
 	evaluateReturns struct {
 		result1 []byte
@@ -29,7 +30,7 @@ type FakePolicy struct {
 	invocationsMutex sync.RWMutex
 }
 
-func (fake *FakePolicy) Evaluate(arg1 context.Context, arg2 string, arg3 interface{}, arg4 string) ([]byte, error) {
+func (fake *FakePolicy) Evaluate(arg1 context.Context, arg2 string, arg3 interface{}, arg4 string, arg5 *int) ([]byte, error) {
 	fake.evaluateMutex.Lock()
 	ret, specificReturn := fake.evaluateReturnsOnCall[len(fake.evaluateArgsForCall)]
 	fake.evaluateArgsForCall = append(fake.evaluateArgsForCall, struct {
@@ -37,13 +38,14 @@ func (fake *FakePolicy) Evaluate(arg1 context.Context, arg2 string, arg3 interfa
 		arg2 string
 		arg3 interface{}
 		arg4 string
-	}{arg1, arg2, arg3, arg4})
+		arg5 *int
+	}{arg1, arg2, arg3, arg4, arg5})
 	stub := fake.EvaluateStub
 	fakeReturns := fake.evaluateReturns
-	fake.recordInvocation("Evaluate", []interface{}{arg1, arg2, arg3, arg4})
+	fake.recordInvocation("Evaluate", []interface{}{arg1, arg2, arg3, arg4, arg5})
 	fake.evaluateMutex.Unlock()
 	if stub != nil {
-		return stub(arg1, arg2, arg3, arg4)
+		return stub(arg1, arg2, arg3, arg4, arg5)
 	}
 	if specificReturn {
 		return ret.result1, ret.result2
@@ -57,17 +59,17 @@ func (fake *FakePolicy) EvaluateCallCount() int {
 	return len(fake.evaluateArgsForCall)
 }
 
-func (fake *FakePolicy) EvaluateCalls(stub func(context.Context, string, interface{}, string) ([]byte, error)) {
+func (fake *FakePolicy) EvaluateCalls(stub func(context.Context, string, interface{}, string, *int) ([]byte, error)) {
 	fake.evaluateMutex.Lock()
 	defer fake.evaluateMutex.Unlock()
 	fake.EvaluateStub = stub
 }
 
-func (fake *FakePolicy) EvaluateArgsForCall(i int) (context.Context, string, interface{}, string) {
+func (fake *FakePolicy) EvaluateArgsForCall(i int) (context.Context, string, interface{}, string, *int) {
 	fake.evaluateMutex.RLock()
 	defer fake.evaluateMutex.RUnlock()
 	argsForCall := fake.evaluateArgsForCall[i]
-	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5
 }
 
 func (fake *FakePolicy) EvaluateReturns(result1 []byte, result2 error) {
diff --git a/internal/service/infohub/infohubfakes/fake_signer.go b/internal/service/infohub/infohubfakes/fake_signer.go
index ba8abb5..db2c0e1 100644
--- a/internal/service/infohub/infohubfakes/fake_signer.go
+++ b/internal/service/infohub/infohubfakes/fake_signer.go
@@ -5,8 +5,8 @@ import (
 	"context"
 	"sync"
 
-	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/internal/service/infohub"
 	"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
+	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/internal/service/infohub"
 )
 
 type FakeSigner struct {
diff --git a/internal/service/infohub/service.go b/internal/service/infohub/service.go
index 00ad890..1c38b6a 100644
--- a/internal/service/infohub/service.go
+++ b/internal/service/infohub/service.go
@@ -26,7 +26,7 @@ type Storage interface {
 }
 
 type Policy interface {
-	Evaluate(ctx context.Context, policy string, data interface{}, evaluationID string) ([]byte, error)
+	Evaluate(ctx context.Context, policy string, data interface{}, evaluationID string, ttl *int) ([]byte, error)
 }
 
 type Cache interface {
@@ -207,7 +207,7 @@ func (s *Service) triggerExport(ctx context.Context, exportCfg *storage.ExportCo
 	s.logger.Info("export triggered", zap.String("exportName", exportCfg.ExportName))
 	for policy, input := range exportCfg.Policies {
 		cacheKey := exportCacheKey(exportCfg.ExportName, policy)
-		_, err := s.policy.Evaluate(ctx, policy, input, cacheKey)
+		_, err := s.policy.Evaluate(ctx, policy, input, cacheKey, exportCfg.TTL)
 		if err != nil {
 			return err
 		}
diff --git a/internal/service/infohub/service_test.go b/internal/service/infohub/service_test.go
index c17520b..121971a 100644
--- a/internal/service/infohub/service_test.go
+++ b/internal/service/infohub/service_test.go
@@ -9,6 +9,7 @@ import (
 	"go.uber.org/zap"
 
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/errors"
+	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/ptr"
 	goasigner "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/gen/infohub"
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/internal/service/infohub"
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/internal/service/infohub/infohubfakes"
@@ -85,6 +86,7 @@ func TestService_Export(t *testing.T) {
 						ExportName: "testexport",
 						Contexts:   []string{"https://www.w3.org/2018/credentials/examples/v1"},
 						Policies:   map[string]interface{}{"test/test/1.0": map[string]interface{}{"hello": "test world"}},
+						TTL:        ptr.Int(60),
 					}, nil
 				},
 			},
@@ -94,7 +96,7 @@ func TestService_Export(t *testing.T) {
 				},
 			},
 			policy: &infohubfakes.FakePolicy{
-				EvaluateStub: func(ctx context.Context, policy string, input interface{}, cachekey string) ([]byte, error) {
+				EvaluateStub: func(ctx context.Context, policy string, input interface{}, cachekey string, ttl *int) ([]byte, error) {
 					return nil, errors.New("error evaluation policy")
 				},
 			},
@@ -119,7 +121,32 @@ func TestService_Export(t *testing.T) {
 				},
 			},
 			policy: &infohubfakes.FakePolicy{
-				EvaluateStub: func(ctx context.Context, policy string, input interface{}, cachekey string) ([]byte, error) {
+				EvaluateStub: func(ctx context.Context, policy string, input interface{}, cachekey string, ttl *int) ([]byte, error) {
+					return []byte(`{"allow":"true"}`), nil
+				},
+			},
+			res: map[string]interface{}{"result": "export request is accepted"},
+		},
+		{
+			name: "export triggering successfully with TTL provided in export configuration",
+			req:  &goasigner.ExportRequest{ExportName: "testexport"},
+			storage: &infohubfakes.FakeStorage{
+				ExportConfigurationStub: func(ctx context.Context, s string) (*storage.ExportConfiguration, error) {
+					return &storage.ExportConfiguration{
+						ExportName: "testexport",
+						Contexts:   []string{"https://www.w3.org/2018/credentials/examples/v1"},
+						Policies:   map[string]interface{}{"test/test/1.0": map[string]interface{}{"hello": "test world"}},
+						TTL:        ptr.Int(60),
+					}, nil
+				},
+			},
+			cache: &infohubfakes.FakeCache{
+				GetStub: func(ctx context.Context, key string, namespace string, scope string) ([]byte, error) {
+					return nil, errors.New(errors.NotFound, "no data")
+				},
+			},
+			policy: &infohubfakes.FakePolicy{
+				EvaluateStub: func(ctx context.Context, policy string, input interface{}, cachekey string, ttl *int) ([]byte, error) {
 					return []byte(`{"allow":"true"}`), nil
 				},
 			},
diff --git a/internal/storage/storage.go b/internal/storage/storage.go
index c495594..542a114 100644
--- a/internal/storage/storage.go
+++ b/internal/storage/storage.go
@@ -15,6 +15,7 @@ type ExportConfiguration struct {
 	ExportName string
 	Contexts   []string
 	Policies   map[string]interface{}
+	TTL        *int
 }
 
 type Storage struct {
diff --git a/vendor/gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/ptr/ptr.go b/vendor/gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/ptr/ptr.go
new file mode 100644
index 0000000000000000000000000000000000000000..fd522b7a70d7449dccc01ee3b2b3181eb9e7600e
GIT binary patch
literal 1629
zcmdPb;tEJi&Q45ERVXMaQb^9vD@n}ED^@5i$;`<tsZ>ZS%}XxH%+D)UNXrLHm!%e!
zWagzSlqKerrWPxd<SP{9XXcfp7C}YyxU}@S3J^weab@Nf<QJ7FD3xU9rYdo9>FX;v
z<>%)p6s4Aw7UdNyB*G0S$yZ2JNCL@$4cFrWSq@gLkpvdkRL}xTS95VfbStPOan(YM
ztSm{zX(UJv#mLH%RFILCC8;1ILDE=^^vo;4VPc*_W?l)zzfebd=9Oq<f<!eHv_Nu5
z#$`fX=$ThyfzLb(bOS9QCR#v@v{1lqrlA==Lk-Q)O*J%w7;9(-G1t%xhrz~1_zX5S
zLO0mh2x73Y5yW6)BOC^sncy?n%mm$FGZToxW+o7W%}lTv9105dBJ63Z6eNe706>a0
zN)<rjnhIJV3fag~XpDhW;fgY_UeqW9D~Fm2iZqb1D6xiYF3xBJ8;llhAd?Nvphklu
z4rDfJ%pn_&GwQ&GqeUIaaAPB=;o!&v8IBrz$cE#LKCt0v(FZcz%mivUI08Y2qsAc2
zaJQWN#1h<2PlHM$$0JmWMw$XtR#QO>%0iCNG-!l^mE(3lSSOkXpju!yfV}`yhm;{<
zHUyRCrQ%543Pm6}WY>cfYZQUSH5IhL(nv-YK^+}jQUoe*i?Ao{Vu&oVu@DU!#R?EP
vO$99o135&Bp@xTK=BDCuFQ~lM11mr_9VDPpq5zlFRM3L6k!>j9s^tOz=6VoD

literal 0
HcmV?d00001

diff --git a/vendor/modules.txt b/vendor/modules.txt
index a0eed4fc9ee4a11624086e5ea747f3230c82a674..806589fdd47cf06c1f06e8e69d6fdd8fdc8ff58e 100644
GIT binary patch
delta 29
lcmX@pz&NFmaYL-uWCKkXwt|u(E@g$ug4)uXtF$hO0sxpQ37h}`

delta 21
dcmbQz$atoKaYL*Yld{5OMs4ZMhqNw<0sv8I2S5M-

-- 
GitLab