Merge remote-tracking branch 'origin/main' into ds-apiserver-with-configs
This commit is contained in:
+2
-2
@@ -62,13 +62,13 @@ For more details on contact points, including how to test them and enable notifi
|
||||
|
||||
| Key | Description |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Title | The issue title. Supports templating. Max length is 255 characters. |
|
||||
| Summary | The issue title. Supports templating. Max length is 255 characters. |
|
||||
| Description | The description of the issue. Depending on version of the API, it can be a text, Markdown, or JSON (v3 API only). Maximum size of the field is 32kb.<br>**Note:** JSON is not limited by the client, and if it exceeds the size, the API is likely to reject the request. |
|
||||
| Labels | Custom labels can be added to organize and filter issues created in Jira. Supports templating, allowing dynamic label generation based on alert data. |
|
||||
| Priority | The priority level of the issue (e.g., `Low`, `Medium`, `High`, `Critical`). <br>Ensure that the priority value matches the available options for your Jira instance. You can customize priority levels in Jira [here](https://support.atlassian.com/jira-cloud-administration/docs/configure-priorities/). |
|
||||
| Resolve Transition | The transition name to move the issue to a resolved state when an alert is resolved. Ensure that the value matches a valid transition available in your Jira workflow for the specified issue type. If this field is empty, the issue will not be transitioned to Done. |
|
||||
| Reopen Transition | The transition name to move the issue back to an open state when an alert reoccurs. Ensure that the value matches a valid transition available in your Jira workflow for the specified issue type. If this field is empty, the issue will not be reopened. |
|
||||
| Reopen Duration | The time duration (in minutes) to control whether to reopen an issue that was closed within this duration or create a new one. If not specified, the most recent issue that matches the deduplication key will be updated and reopened (if reopen transition is specified). |
|
||||
| Ignored Resolution | Specify a resolution status that should be ignored when searching for existing issues. For example, issues with this resolution will not be reopened or updated by subsequent alerts. |
|
||||
| "Won't fix" Transition | Specify a resolution status that should be ignored when searching for existing issues. For example, issues with this resolution will not be reopened or updated by subsequent alerts. |
|
||||
| Deduplication Key Field | Custom field to store the deduplication key. Must be a text field. <br> If not specified, the deduplication key is added to labels in the format of `ALERT(hash sum)`. See [Jira documentation](https://support.atlassian.com/jira-cloud-administration/docs/create-a-custom-field/) for how to create custom fields. |
|
||||
| Fields | Allows to configure custom fields of Jira issue. The field name should be of the format like `customfield_10001`. |
|
||||
|
||||
@@ -32,9 +32,21 @@ func NewOpenFGAServer(cfg setting.ZanzanaServerSettings, store storage.OpenFGADa
|
||||
opts := []server.OpenFGAServiceV1Option{
|
||||
server.WithDatastore(store),
|
||||
server.WithLogger(zlogger.New(logger)),
|
||||
server.WithCheckQueryCacheEnabled(cfg.CheckQueryCache),
|
||||
server.WithCheckQueryCacheTTL(cfg.CheckQueryCacheTTL),
|
||||
server.WithCheckCacheLimit(cfg.CacheSettings.CheckCacheLimit),
|
||||
server.WithCacheControllerEnabled(cfg.CacheSettings.CacheControllerEnabled),
|
||||
server.WithCacheControllerTTL(cfg.CacheSettings.CacheControllerTTL),
|
||||
server.WithCheckQueryCacheEnabled(cfg.CacheSettings.CheckQueryCacheEnabled),
|
||||
server.WithCheckQueryCacheTTL(cfg.CacheSettings.CheckQueryCacheTTL),
|
||||
server.WithCheckIteratorCacheEnabled(cfg.CacheSettings.CheckIteratorCacheEnabled),
|
||||
server.WithCheckIteratorCacheMaxResults(cfg.CacheSettings.CheckIteratorCacheMaxResults),
|
||||
server.WithCheckIteratorCacheTTL(cfg.CacheSettings.CheckIteratorCacheTTL),
|
||||
server.WithListObjectsMaxResults(cfg.ListObjectsMaxResults),
|
||||
server.WithListObjectsIteratorCacheEnabled(cfg.CacheSettings.ListObjectsIteratorCacheEnabled),
|
||||
server.WithListObjectsIteratorCacheMaxResults(cfg.CacheSettings.ListObjectsIteratorCacheMaxResults),
|
||||
server.WithListObjectsIteratorCacheTTL(cfg.CacheSettings.ListObjectsIteratorCacheTTL),
|
||||
server.WithSharedIteratorEnabled(cfg.CacheSettings.SharedIteratorEnabled),
|
||||
server.WithSharedIteratorLimit(cfg.CacheSettings.SharedIteratorLimit),
|
||||
server.WithSharedIteratorTTL(cfg.CacheSettings.SharedIteratorTTL),
|
||||
server.WithListObjectsDeadline(cfg.ListObjectsDeadline),
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ func NewServer(cfg setting.ZanzanaServerSettings, openfga OpenFGAServer, logger
|
||||
storesMU: &sync.Mutex{},
|
||||
stores: make(map[string]storeInfo),
|
||||
cfg: cfg,
|
||||
cache: localcache.New(cfg.CheckQueryCacheTTL, cacheCleanInterval),
|
||||
cache: localcache.New(cfg.CacheSettings.CheckQueryCacheTTL, cacheCleanInterval),
|
||||
logger: logger,
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ func (s *Server) listObjects(ctx context.Context, req *openfgav1.ListObjectsRequ
|
||||
fn = s.streamedListObjects
|
||||
}
|
||||
|
||||
if s.cfg.CheckQueryCache {
|
||||
if s.cfg.CacheSettings.CheckQueryCacheEnabled {
|
||||
return s.listObjectCached(ctx, req, fn)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,8 @@ type ZanzanaServerSettings struct {
|
||||
// OpenFGA http server address which allows to connect with fga cli.
|
||||
// Can only be used in dev mode.
|
||||
OpenFGAHttpAddr string
|
||||
// Enable cache for Check() requests
|
||||
CheckQueryCache bool
|
||||
// TTL for cached requests. Default is 10 seconds.
|
||||
CheckQueryCacheTTL time.Duration
|
||||
// Cache settings
|
||||
CacheSettings OpenFgaCacheSettings
|
||||
// Max number of results returned by ListObjects() query. Default is 1000.
|
||||
ListObjectsMaxResults uint32
|
||||
// Deadline for the ListObjects() query. Default is 3 seconds.
|
||||
@@ -50,6 +48,54 @@ type ZanzanaServerSettings struct {
|
||||
AllowInsecure bool
|
||||
}
|
||||
|
||||
// Parameters to configure OpenFGA cache.
|
||||
type OpenFgaCacheSettings struct {
|
||||
// Number of items that will be kept in the in-memory cache used to resolve Check queries.
|
||||
// If CheckQueryCacheEnabled or CheckIteratorCacheEnabled, this is the size limit of the cache
|
||||
CheckCacheLimit uint32
|
||||
// When enabled, cache controller will verify whether check subproblem cache and check
|
||||
// iterator cache needs to be invalidated when there is a check or list objects API request.
|
||||
// The invalidation determination is based on whether there are recent write or deletes for
|
||||
// the store. This feature allows a larger check-query-cache-ttl and check-iterator-cache-ttl
|
||||
// at the expense of additional datastore queries for recent writes and deletes.
|
||||
CacheControllerEnabled bool
|
||||
// Specifies how frequently the cache controller checks for Writes occurring. While the
|
||||
// cache controller result is cached, the server will not read the datastore to check
|
||||
// whether subproblem cache and iterator cache needs to be invalidated.
|
||||
CacheControllerTTL time.Duration
|
||||
// Enables in-memory caching of Check subproblems. For example, if you have a relation
|
||||
// `define viewer: owner or editor`, and the query is `Check(user:anne, viewer, doc:1)`,
|
||||
// we'll evaluate the `owner` relation and the `editor` relation and cache both results:
|
||||
// `(user:anne, viewer, doc:1) -> allowed=true` and `(user:anne, owner, doc:1) -> allowed=true`.
|
||||
CheckQueryCacheEnabled bool
|
||||
// Time that items will be kept in the cache of Check subproblems
|
||||
CheckQueryCacheTTL time.Duration
|
||||
// Enables in-memory caching of database iterators. Each iterator is the result of a database
|
||||
// query, for example, usersets related to a specific object, or objects related to a specific
|
||||
// user, up to a certain number of tuples per iterator
|
||||
CheckIteratorCacheEnabled bool
|
||||
// Number of tuples that will be stored for each database iterator
|
||||
CheckIteratorCacheMaxResults uint32
|
||||
// Time that items will be kept in the cache of database iterators
|
||||
CheckIteratorCacheTTL time.Duration
|
||||
// Enables in-memory caching of database iterators for ListObjects. Each iterator is the result
|
||||
// of a database query, for example, usersets related to a specific object, or objects related
|
||||
// to a specific user, up to a certain number of tuples per iterator
|
||||
ListObjectsIteratorCacheEnabled bool
|
||||
// Number of tuples that will be stored for each ListObjects database iterator
|
||||
ListObjectsIteratorCacheMaxResults uint32
|
||||
// Time that items will be kept in the cache of ListObjects database iterators
|
||||
ListObjectsIteratorCacheTTL time.Duration
|
||||
// Enables sharing of datastore iterators with different consumers. Each iterator is the result
|
||||
// of a database query, for example usersets related to a specific object, or objects related
|
||||
// to a specific user, up to a certain number of tuples per iterator
|
||||
SharedIteratorEnabled bool
|
||||
// Limit of the number of iterators that can be shared when shared iterator is enabled
|
||||
SharedIteratorLimit uint32
|
||||
// Time that shared iterators will be kept in the cache
|
||||
SharedIteratorTTL time.Duration
|
||||
}
|
||||
|
||||
func (cfg *Cfg) readZanzanaSettings() {
|
||||
zc := ZanzanaClientSettings{}
|
||||
clientSec := cfg.SectionWithEnvOverrides("zanzana.client")
|
||||
@@ -73,13 +119,27 @@ func (cfg *Cfg) readZanzanaSettings() {
|
||||
serverSec := cfg.SectionWithEnvOverrides("zanzana.server")
|
||||
|
||||
zs.OpenFGAHttpAddr = serverSec.Key("http_addr").MustString("127.0.0.1:8080")
|
||||
zs.CheckQueryCache = serverSec.Key("check_query_cache").MustBool(true)
|
||||
zs.CheckQueryCacheTTL = serverSec.Key("check_query_cache_ttl").MustDuration(10 * time.Second)
|
||||
zs.ListObjectsDeadline = serverSec.Key("list_objects_deadline").MustDuration(3 * time.Second)
|
||||
zs.ListObjectsMaxResults = uint32(serverSec.Key("list_objects_max_results").MustUint(1000))
|
||||
zs.UseStreamedListObjects = serverSec.Key("use_streamed_list_objects").MustBool(false)
|
||||
zs.SigningKeysURL = serverSec.Key("signing_keys_url").MustString("")
|
||||
zs.AllowInsecure = serverSec.Key("allow_insecure").MustBool(false)
|
||||
|
||||
// Cache settings
|
||||
zs.CacheSettings.CheckCacheLimit = uint32(serverSec.Key("check_cache_limit").MustUint(10000))
|
||||
zs.CacheSettings.CacheControllerEnabled = serverSec.Key("cache_controller_enabled").MustBool(false)
|
||||
zs.CacheSettings.CacheControllerTTL = serverSec.Key("cache_controller_ttl").MustDuration(10 * time.Second)
|
||||
zs.CacheSettings.CheckQueryCacheEnabled = serverSec.Key("check_query_cache_enabled").MustBool(true)
|
||||
zs.CacheSettings.CheckQueryCacheTTL = serverSec.Key("check_query_cache_ttl").MustDuration(10 * time.Second)
|
||||
zs.CacheSettings.CheckIteratorCacheEnabled = serverSec.Key("check_iterator_cache_enabled").MustBool(false)
|
||||
zs.CacheSettings.CheckIteratorCacheMaxResults = uint32(serverSec.Key("check_iterator_cache_max_results").MustUint(1000))
|
||||
zs.CacheSettings.CheckIteratorCacheTTL = serverSec.Key("check_iterator_cache_ttl").MustDuration(10 * time.Second)
|
||||
zs.CacheSettings.ListObjectsIteratorCacheEnabled = serverSec.Key("list_objects_iterator_cache_enabled").MustBool(false)
|
||||
zs.CacheSettings.ListObjectsIteratorCacheMaxResults = uint32(serverSec.Key("list_objects_iterator_cache_max_results").MustUint(1000))
|
||||
zs.CacheSettings.ListObjectsIteratorCacheTTL = serverSec.Key("list_objects_iterator_cache_ttl").MustDuration(10 * time.Second)
|
||||
zs.CacheSettings.SharedIteratorEnabled = serverSec.Key("shared_iterator_enabled").MustBool(false)
|
||||
zs.CacheSettings.SharedIteratorLimit = uint32(serverSec.Key("shared_iterator_limit").MustUint(1000))
|
||||
zs.CacheSettings.SharedIteratorTTL = serverSec.Key("shared_iterator_ttl").MustDuration(10 * time.Second)
|
||||
|
||||
cfg.ZanzanaServer = zs
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ func newFrame(schema *arrow.Schema) *data.Frame {
|
||||
|
||||
func newField(f arrow.Field) *data.Field {
|
||||
switch f.Type.ID() {
|
||||
case arrow.STRING:
|
||||
case arrow.STRING, arrow.STRING_VIEW:
|
||||
return newDataField[string](f)
|
||||
case arrow.FLOAT32:
|
||||
return newDataField[float32](f)
|
||||
@@ -239,6 +239,8 @@ func copyData(field *data.Field, col arrow.Array) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case arrow.STRING_VIEW:
|
||||
copyBasic[string](field, array.NewStringViewData(colData))
|
||||
case arrow.STRING:
|
||||
copyBasic[string](field, array.NewStringData(colData))
|
||||
case arrow.UINT8:
|
||||
|
||||
@@ -469,6 +469,43 @@ func TestCopyData_Float64(t *testing.T) {
|
||||
assert.Equal(t, float64(3.3), *field.CopyAt(2).(*float64))
|
||||
}
|
||||
|
||||
func TestCopyData_StringView(t *testing.T) {
|
||||
// Non-nullable StringView
|
||||
field := data.NewField("field", nil, []string{})
|
||||
builder := array.NewStringViewBuilder(memory.DefaultAllocator)
|
||||
builder.Append("apple")
|
||||
builder.Append("banana")
|
||||
builder.Append("cherry")
|
||||
arr := builder.NewArray()
|
||||
defer arr.Release()
|
||||
|
||||
svArr := array.NewStringViewData(arr.Data())
|
||||
defer svArr.Release()
|
||||
|
||||
err := copyData(field, svArr)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "apple", field.CopyAt(0))
|
||||
assert.Equal(t, "banana", field.CopyAt(1))
|
||||
assert.Equal(t, "cherry", field.CopyAt(2))
|
||||
|
||||
// Nullable StringView
|
||||
field = data.NewField("field", nil, []*string{})
|
||||
builder = array.NewStringViewBuilder(memory.DefaultAllocator)
|
||||
builder.Append("dog")
|
||||
builder.AppendNull()
|
||||
builder.Append("cat")
|
||||
arr2 := builder.NewArray()
|
||||
defer arr2.Release()
|
||||
svArr2 := array.NewStringViewData(arr2.Data())
|
||||
defer svArr2.Release()
|
||||
|
||||
err = copyData(field, svArr2)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "dog", *(field.CopyAt(0).(*string)))
|
||||
assert.Nil(t, field.CopyAt(1))
|
||||
assert.Equal(t, "cat", *(field.CopyAt(2).(*string)))
|
||||
}
|
||||
|
||||
func TestCustomMetadata(t *testing.T) {
|
||||
schema := arrow.NewSchema([]arrow.Field{
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user