Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache network settings #251

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions handlers/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
"github.com/labstack/echo/v4"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-rest-gw/handlers/apiserver"
"github.com/nspcc-dev/neofs-rest-gw/internal/cache"
"github.com/nspcc-dev/neofs-rest-gw/internal/util"
"github.com/nspcc-dev/neofs-rest-gw/metrics"
"github.com/nspcc-dev/neofs-sdk-go/netmap"
"github.com/nspcc-dev/neofs-sdk-go/pool"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/user"
Expand Down Expand Up @@ -45,6 +47,10 @@
Verb session.ContainerVerb
}

type networkInfoGetter interface {
NetworkInfo(ctx context.Context) (netmap.NetworkInfo, error)
}

const (
// bearerCookieName is the name of the bearer cookie.
bearerCookieName = "Bearer"
Expand Down Expand Up @@ -75,6 +81,7 @@
pprofService: prm.PprofService,
gateMetric: prm.GateMetric,
serviceShutdownTimeout: prm.ServiceShutdownTimeout,
networkInfoGetter: cache.NewNetworkInfoCache(prm.Pool),

Check warning on line 84 in handlers/api.go

View check run for this annotation

Codecov / codecov/patch

handlers/api.go#L84

Added line #L84 was not covered by tests
}, nil
}

Expand Down Expand Up @@ -141,6 +148,7 @@
prometheusService *metrics.Service
pprofService *metrics.Service
serviceShutdownTimeout time.Duration
networkInfoGetter networkInfoGetter
}

func (a *RestAPI) StartCallback() {
Expand Down
22 changes: 10 additions & 12 deletions handlers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
"github.com/labstack/echo/v4"
"github.com/nspcc-dev/neofs-rest-gw/handlers/apiserver"
"github.com/nspcc-dev/neofs-rest-gw/internal/util"
"github.com/nspcc-dev/neofs-sdk-go/client"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/pool"
"github.com/nspcc-dev/neofs-sdk-go/user"
)

Expand Down Expand Up @@ -91,10 +89,10 @@

if isObject {
prm := newObjectParams(commonPrm, token)
response[i], err = prepareObjectToken(ctx.Request().Context(), prm, a.pool, a.signer.UserID())
response[i], err = prepareObjectToken(ctx.Request().Context(), prm, a.networkInfoGetter, a.signer.UserID())

Check warning on line 92 in handlers/auth.go

View check run for this annotation

Codecov / codecov/patch

handlers/auth.go#L92

Added line #L92 was not covered by tests
} else {
prm := newContainerParams(commonPrm, token)
response[i], err = prepareContainerTokens(ctx.Request().Context(), prm, a.pool, a.signer.Public())
response[i], err = prepareContainerTokens(ctx.Request().Context(), prm, a.networkInfoGetter, a.signer.Public())

Check warning on line 95 in handlers/auth.go

View check run for this annotation

Codecov / codecov/patch

handlers/auth.go#L95

Added line #L95 was not covered by tests
}

if err != nil {
Expand Down Expand Up @@ -136,7 +134,7 @@
return ctx.JSON(http.StatusOK, resp)
}

func prepareObjectToken(ctx context.Context, params objectTokenParams, pool *pool.Pool, owner user.ID) (*apiserver.TokenResponse, error) {
func prepareObjectToken(ctx context.Context, params objectTokenParams, networkInfoGetter networkInfoGetter, owner user.ID) (*apiserver.TokenResponse, error) {

Check warning on line 137 in handlers/auth.go

View check run for this annotation

Codecov / codecov/patch

handlers/auth.go#L137

Added line #L137 was not covered by tests
btoken, err := util.ToNativeObjectToken(params.Records)
if err != nil {
return nil, fmt.Errorf("couldn't transform token to native: %w", err)
Expand All @@ -152,7 +150,7 @@
btoken.ForUser(owner)
}

iat, exp, err := getTokenLifetime(ctx, pool, params.XBearerLifetime)
iat, exp, err := getTokenLifetime(ctx, networkInfoGetter, params.XBearerLifetime)

Check warning on line 153 in handlers/auth.go

View check run for this annotation

Codecov / codecov/patch

handlers/auth.go#L153

Added line #L153 was not covered by tests
if err != nil {
return nil, fmt.Errorf("couldn't get lifetime: %w", err)
}
Expand All @@ -168,8 +166,8 @@
}, nil
}

func prepareContainerTokens(ctx context.Context, params containerTokenParams, pool *pool.Pool, pubKey neofscrypto.PublicKey) (*apiserver.TokenResponse, error) {
iat, exp, err := getTokenLifetime(ctx, pool, params.XBearerLifetime)
func prepareContainerTokens(ctx context.Context, params containerTokenParams, networkInfoGetter networkInfoGetter, pubKey neofscrypto.PublicKey) (*apiserver.TokenResponse, error) {
iat, exp, err := getTokenLifetime(ctx, networkInfoGetter, params.XBearerLifetime)

Check warning on line 170 in handlers/auth.go

View check run for this annotation

Codecov / codecov/patch

handlers/auth.go#L169-L170

Added lines #L169 - L170 were not covered by tests
if err != nil {
return nil, fmt.Errorf("couldn't get lifetime: %w", err)
}
Expand Down Expand Up @@ -204,17 +202,17 @@
}, nil
}

func getCurrentEpoch(ctx context.Context, p *pool.Pool) (uint64, error) {
netInfo, err := p.NetworkInfo(ctx, client.PrmNetworkInfo{})
func getCurrentEpoch(ctx context.Context, networkInfoGetter networkInfoGetter) (uint64, error) {
netInfo, err := networkInfoGetter.NetworkInfo(ctx)

Check warning on line 206 in handlers/auth.go

View check run for this annotation

Codecov / codecov/patch

handlers/auth.go#L205-L206

Added lines #L205 - L206 were not covered by tests
if err != nil {
return 0, fmt.Errorf("couldn't get netwokr info: %w", err)
}

return netInfo.CurrentEpoch(), nil
}

func getTokenLifetime(ctx context.Context, p *pool.Pool, expDuration uint64) (uint64, uint64, error) {
currEpoch, err := getCurrentEpoch(ctx, p)
func getTokenLifetime(ctx context.Context, networkInfoGetter networkInfoGetter, expDuration uint64) (uint64, uint64, error) {
currEpoch, err := getCurrentEpoch(ctx, networkInfoGetter)

Check warning on line 215 in handlers/auth.go

View check run for this annotation

Codecov / codecov/patch

handlers/auth.go#L214-L215

Added lines #L214 - L215 were not covered by tests
if err != nil {
return 0, 0, err
}
Expand Down
13 changes: 11 additions & 2 deletions handlers/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
return ctx.JSON(http.StatusBadRequest, resp)
}

cnrID, err := createContainer(ctx.Request().Context(), a.pool, stoken, body, params, a.signer)
cnrID, err := createContainer(ctx.Request().Context(), a.pool, stoken, body, params, a.signer, a.networkInfoGetter)

Check warning on line 67 in handlers/containers.go

View check run for this annotation

Codecov / codecov/patch

handlers/containers.go#L67

Added line #L67 was not covered by tests
if err != nil {
resp := a.logAndGetErrorResponse("create container", err)
return ctx.JSON(http.StatusBadRequest, resp)
Expand Down Expand Up @@ -381,7 +381,7 @@
return tableResp, nil
}

func createContainer(ctx context.Context, p *pool.Pool, stoken session.Container, request apiserver.ContainerPutInfo, params apiserver.PutContainerParams, signer user.Signer) (cid.ID, error) {
func createContainer(ctx context.Context, p *pool.Pool, stoken session.Container, request apiserver.ContainerPutInfo, params apiserver.PutContainerParams, signer user.Signer, networkInfoGetter networkInfoGetter) (cid.ID, error) {

Check warning on line 384 in handlers/containers.go

View check run for this annotation

Codecov / codecov/patch

handlers/containers.go#L384

Added line #L384 was not covered by tests
if request.PlacementPolicy == "" {
request.PlacementPolicy = defaultPlacementPolicy
}
Expand All @@ -406,6 +406,15 @@
cnr.SetBasicACL(basicACL)
cnr.SetOwner(stoken.Issuer())

ni, err := networkInfoGetter.NetworkInfo(ctx)
roman-khimov marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return cid.ID{}, fmt.Errorf("couldn't get network info: %w", err)
}

Check warning on line 412 in handlers/containers.go

View check run for this annotation

Codecov / codecov/patch

handlers/containers.go#L409-L412

Added lines #L409 - L412 were not covered by tests

if ni.HomomorphicHashingDisabled() {
cnr.DisableHomomorphicHashing()
}

Check warning on line 416 in handlers/containers.go

View check run for this annotation

Codecov / codecov/patch

handlers/containers.go#L414-L416

Added lines #L414 - L416 were not covered by tests

cnr.SetCreationTime(time.Now())

if request.ContainerName != "" {
Expand Down
2 changes: 1 addition & 1 deletion handlers/newObjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@

addExpirationHeaders(filtered, params)
if needParseExpiration(filtered) {
epochDuration, err := getEpochDurations(ctx.Request().Context(), a.pool)
epochDuration, err := getEpochDurations(ctx.Request().Context(), a.networkInfoGetter)

Check warning on line 65 in handlers/newObjects.go

View check run for this annotation

Codecov / codecov/patch

handlers/newObjects.go#L65

Added line #L65 was not covered by tests
if err != nil {
resp := a.logAndGetErrorResponse("could not get epoch durations from network info", err)
return ctx.JSON(http.StatusBadRequest, resp)
Expand Down
4 changes: 2 additions & 2 deletions handlers/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
DefaultTimestamp: a.defaultTimestamp,
DefaultFileName: body.FileName,
}
attributes, err := getObjectAttributes(ctx.Request().Context(), a.pool, body.Attributes, prm)
attributes, err := getObjectAttributes(ctx.Request().Context(), a.networkInfoGetter, body.Attributes, prm)

Check warning on line 108 in handlers/objects.go

View check run for this annotation

Codecov / codecov/patch

handlers/objects.go#L108

Added line #L108 was not covered by tests
if err != nil {
resp := a.logAndGetErrorResponse("failed to get object attributes", err)
return ctx.JSON(http.StatusBadRequest, resp)
Expand Down Expand Up @@ -940,7 +940,7 @@
}

if needParseExpiration(filtered) {
epochDuration, err := getEpochDurations(ctx.Request().Context(), a.pool)
epochDuration, err := getEpochDurations(ctx.Request().Context(), a.networkInfoGetter)

Check warning on line 943 in handlers/objects.go

View check run for this annotation

Codecov / codecov/patch

handlers/objects.go#L943

Added line #L943 was not covered by tests
if err != nil {
resp := a.logAndGetErrorResponse("could not get epoch durations from network info", err)
return ctx.JSON(http.StatusBadRequest, resp)
Expand Down
9 changes: 4 additions & 5 deletions handlers/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"github.com/nspcc-dev/neofs-sdk-go/container/acl"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/nspcc-dev/neofs-sdk-go/pool"
"github.com/nspcc-dev/neofs-sdk-go/session"
"go.uber.org/zap"
)
Expand Down Expand Up @@ -55,7 +54,7 @@
limitDefault = 100
)

func getObjectAttributes(ctx context.Context, pool *pool.Pool, attrs []apiserver.Attribute, prm PrmAttributes) ([]object.Attribute, error) {
func getObjectAttributes(ctx context.Context, networkInfoGetter networkInfoGetter, attrs []apiserver.Attribute, prm PrmAttributes) ([]object.Attribute, error) {

Check warning on line 57 in handlers/util.go

View check run for this annotation

Codecov / codecov/patch

handlers/util.go#L57

Added line #L57 was not covered by tests
headers := make(map[string]string, len(attrs))

for _, attr := range attrs {
Expand All @@ -64,7 +63,7 @@
delete(headers, object.AttributeFileName)

if needParseExpiration(headers) {
epochDuration, err := getEpochDurations(ctx, pool)
epochDuration, err := getEpochDurations(ctx, networkInfoGetter)

Check warning on line 66 in handlers/util.go

View check run for this annotation

Codecov / codecov/patch

handlers/util.go#L66

Added line #L66 was not covered by tests
if err != nil {
return nil, fmt.Errorf("could not get epoch durations from network info: %w", err)
}
Expand All @@ -91,8 +90,8 @@
return attributes, nil
}

func getEpochDurations(ctx context.Context, p *pool.Pool) (*epochDurations, error) {
networkInfo, err := p.NetworkInfo(ctx, client.PrmNetworkInfo{})
func getEpochDurations(ctx context.Context, networkInfoGetter networkInfoGetter) (*epochDurations, error) {
networkInfo, err := networkInfoGetter.NetworkInfo(ctx)

Check warning on line 94 in handlers/util.go

View check run for this annotation

Codecov / codecov/patch

handlers/util.go#L93-L94

Added lines #L93 - L94 were not covered by tests
if err != nil {
return nil, err
}
Expand Down
51 changes: 51 additions & 0 deletions internal/cache/networkinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package cache

import (
"context"
"fmt"
"sync"
"time"

"github.com/nspcc-dev/neofs-sdk-go/client"
"github.com/nspcc-dev/neofs-sdk-go/netmap"
"github.com/nspcc-dev/neofs-sdk-go/pool"
)

type (
// NetworkInfo is cache wrapper for the network info.
NetworkInfo struct {
p *pool.Pool
ttl time.Duration

mu *sync.Mutex
validUntil time.Time
ni netmap.NetworkInfo
}
)

func NewNetworkInfoCache(p *pool.Pool) *NetworkInfo {
return &NetworkInfo{
p: p,
mu: &sync.Mutex{},
}
}

func (n *NetworkInfo) NetworkInfo(ctx context.Context) (netmap.NetworkInfo, error) {
n.mu.Lock()
defer n.mu.Unlock()

if n.validUntil.After(time.Now()) {
return n.ni, nil
}

ni, err := n.p.NetworkInfo(ctx, client.PrmNetworkInfo{})
roman-khimov marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return netmap.NetworkInfo{}, fmt.Errorf("get network info: %w", err)
}

Check warning on line 44 in internal/cache/networkinfo.go

View check run for this annotation

Codecov / codecov/patch

internal/cache/networkinfo.go#L43-L44

Added lines #L43 - L44 were not covered by tests

n.ttl = time.Duration(int64(ni.EpochDuration())/2*ni.MsPerBlock()) * time.Millisecond
n.validUntil = time.Now().Add(n.ttl)
n.ni = ni

return ni, nil
}
Loading