Skip to content

Commit

Permalink
Merge pull request #73 from appbaseio/feat/query-translate
Browse files Browse the repository at this point in the history
feat: Implement RS API
  • Loading branch information
lakhansamani authored Mar 2, 2020
2 parents 6b19571 + d61bca3 commit 1d5a118
Show file tree
Hide file tree
Showing 18 changed files with 236 additions and 100 deletions.
47 changes: 34 additions & 13 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,24 +172,30 @@ func main() {
// ES v7 and v6 clients
util.NewClient()
// map of specific plugins
sequencedPlugins := []string{"rules.so", "functions.so", "querytranslate.so", "analytics.so"}
sequencedPlugins := []string{"rules.so", "functions.so", "analytics.so"}
sequencedPluginsByPath := make(map[string]string)

var elasticSearchPath string
var elasticSearchPath, reactiveSearchPath string
elasticSearchMiddleware := make([]middleware.Middleware, 0)
reactiveSearchMiddleware := make([]middleware.Middleware, 0)
err := filepath.Walk(pluginDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && filepath.Ext(info.Name()) == ".so" && info.Name() != "elasticsearch.so" {
if util.IsExists(info.Name(), sequencedPlugins) {
sequencedPluginsByPath[info.Name()] = path
} else {
mw, err1 := LoadPluginFromFile(router, path)
if err1 != nil {
return err1
if info.Name() != "querytranslate.so" {
if util.IsExists(info.Name(), sequencedPlugins) {
sequencedPluginsByPath[info.Name()] = path
} else {
plugin, err1 := LoadPluginFromFile(router, path)
if err1 != nil {
return err1
}
reactiveSearchMiddleware = append(reactiveSearchMiddleware, plugin.RSMiddleware()...)
elasticSearchMiddleware = append(elasticSearchMiddleware, plugin.ESMiddleware()...)
}
elasticSearchMiddleware = append(elasticSearchMiddleware, mw...)
} else {
reactiveSearchPath = path
}
} else if info.Name() == "elasticsearch.so" {
elasticSearchPath = path
Expand All @@ -200,13 +206,18 @@ func main() {
for _, pluginName := range sequencedPlugins {
path, _ := sequencedPluginsByPath[pluginName]
if path != "" {
mw, err := LoadPluginFromFile(router, path)
plugin, err := LoadPluginFromFile(router, path)
if err != nil {
log.Fatal("error loading plugins: ", err)
}
elasticSearchMiddleware = append(elasticSearchMiddleware, mw...)
elasticSearchMiddleware = append(elasticSearchMiddleware, plugin.ESMiddleware()...)
reactiveSearchMiddleware = append(reactiveSearchMiddleware, plugin.RSMiddleware()...)
}
}
// Load ReactiveSearch plugin
if reactiveSearchPath != "" {
LoadRSPluginFromFile(router, reactiveSearchPath, reactiveSearchMiddleware)
}
LoadESPluginFromFile(router, elasticSearchPath, elasticSearchMiddleware)
if err != nil {
log.Fatal("error loading plugins: ", err)
Expand Down Expand Up @@ -242,7 +253,7 @@ func LoadPIFromFile(path string) (plugin.Symbol, error) {
}

// LoadPluginFromFile loads a plugin at the given location
func LoadPluginFromFile(router *mux.Router, path string) ([]middleware.Middleware, error) {
func LoadPluginFromFile(router *mux.Router, path string) (plugins.Plugin, error) {
pi, err2 := LoadPIFromFile(path)
if err2 != nil {
return nil, err2
Expand All @@ -253,7 +264,7 @@ func LoadPluginFromFile(router *mux.Router, path string) ([]middleware.Middlewar
if err3 != nil {
return nil, err3
}
return p.ESMiddleware(), nil
return p, nil
}

func LoadESPluginFromFile(router *mux.Router, path string, mw []middleware.Middleware) error {
Expand All @@ -266,6 +277,16 @@ func LoadESPluginFromFile(router *mux.Router, path string, mw []middleware.Middl
return plugins.LoadESPlugin(router, p, mw)
}

func LoadRSPluginFromFile(router *mux.Router, path string, mw []middleware.Middleware) error {
pi, err2 := LoadPIFromFile(path)
if err2 != nil {
return err2
}
var p plugins.RSPlugin
p = *pi.(*plugins.RSPlugin)
return plugins.LoadRSPlugin(router, p, mw)
}

// LoadEnvFromFile loads env vars from envFile. Envs in the file
// should be in KEY=VALUE format.
func LoadEnvFromFile(envFile string) error {
Expand Down
11 changes: 11 additions & 0 deletions model/category/category.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
Suggestions
Auth
Functions
ReactiveSearch
)

// String is an implementation of Stringer interface that returns the string representation of category.Categories.
Expand All @@ -54,6 +55,7 @@ func (c Category) String() string {
"suggestions",
"auth",
"functions",
"reactivesearch",
}[c]
}

Expand Down Expand Up @@ -95,6 +97,8 @@ func (c *Category) UnmarshalJSON(bytes []byte) error {
*c = Auth
case Functions.String():
*c = Functions
case ReactiveSearch.String():
*c = ReactiveSearch
default:
return fmt.Errorf("invalid category encountered: %v", category)
}
Expand Down Expand Up @@ -135,6 +139,8 @@ func (c Category) MarshalJSON() ([]byte, error) {
category = Auth.String()
case Functions:
category = Functions.String()
case ReactiveSearch:
category = ReactiveSearch.String()
default:
return nil, fmt.Errorf("invalid category encountered: %v" + c.String())
}
Expand All @@ -152,6 +158,11 @@ func (c Category) IsFromES() bool {
c == Misc
}

// IsFromRS checks whether the category is of the reactivesearch category.
func (c Category) IsFromRS() bool {
return c == ReactiveSearch
}

// HasACL checks whether the given acl is a value in the category categories.
func (c Category) HasACL(a acl.ACL) bool {
return acl.Contains(c.ACLs(), a)
Expand Down
67 changes: 35 additions & 32 deletions model/permission/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
category.Suggestions,
category.Auth,
category.Functions,
category.ReactiveSearch,
}

defaultOps = []op.Operation{
Expand All @@ -41,40 +42,42 @@ var (
}

defaultLimits = Limits{
IPLimit: 7200,
DocsLimit: 10,
SearchLimit: 10,
IndicesLimit: 10,
CatLimit: 10,
ClustersLimit: 10,
MiscLimit: 10,
UserLimit: 10,
PermissionLimit: 10,
AnalyticsLimit: 10,
RulesLimit: 10,
TemplatesLimit: 10,
SuggestionsLimit: 10,
StreamsLimit: 10,
AuthLimit: 10,
FunctionsLimit: 10,
IPLimit: 7200,
DocsLimit: 10,
SearchLimit: 10,
IndicesLimit: 10,
CatLimit: 10,
ClustersLimit: 10,
MiscLimit: 10,
UserLimit: 10,
PermissionLimit: 10,
AnalyticsLimit: 10,
RulesLimit: 10,
TemplatesLimit: 10,
SuggestionsLimit: 10,
StreamsLimit: 10,
AuthLimit: 10,
FunctionsLimit: 10,
ReactiveSearchLimit: 10,
}

defaultAdminLimits = Limits{
IPLimit: 7200,
DocsLimit: 30,
SearchLimit: 30,
IndicesLimit: 30,
CatLimit: 30,
ClustersLimit: 30,
MiscLimit: 30,
UserLimit: 30,
PermissionLimit: 30,
AnalyticsLimit: 30,
RulesLimit: 30,
TemplatesLimit: 30,
SuggestionsLimit: 30,
StreamsLimit: 30,
AuthLimit: 30,
FunctionsLimit: 30,
IPLimit: 7200,
DocsLimit: 30,
SearchLimit: 30,
IndicesLimit: 30,
CatLimit: 30,
ClustersLimit: 30,
MiscLimit: 30,
UserLimit: 30,
PermissionLimit: 30,
AnalyticsLimit: 30,
RulesLimit: 30,
TemplatesLimit: 30,
SuggestionsLimit: 30,
StreamsLimit: 30,
AuthLimit: 30,
FunctionsLimit: 30,
ReactiveSearchLimit: 30,
}
)
39 changes: 23 additions & 16 deletions model/permission/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,23 @@ type Permission struct {

// Limits defines the rate limits for each category.
type Limits struct {
IPLimit int64 `json:"ip_limit"`
DocsLimit int64 `json:"docs_limit"`
SearchLimit int64 `json:"search_limit"`
IndicesLimit int64 `json:"indices_limit"`
CatLimit int64 `json:"cat_limit"`
ClustersLimit int64 `json:"clusters_limit"`
MiscLimit int64 `json:"misc_limit"`
UserLimit int64 `json:"user_limit"`
PermissionLimit int64 `json:"permission_limit"`
AnalyticsLimit int64 `json:"analytics_limit"`
RulesLimit int64 `json:"rules_limit"`
TemplatesLimit int64 `json:"templates_limit"`
SuggestionsLimit int64 `json:"suggestions_limit"`
StreamsLimit int64 `json:"streams_limit"`
AuthLimit int64 `json:"auth_limit"`
FunctionsLimit int64 `json:"functions_limit"`
IPLimit int64 `json:"ip_limit"`
DocsLimit int64 `json:"docs_limit"`
SearchLimit int64 `json:"search_limit"`
IndicesLimit int64 `json:"indices_limit"`
CatLimit int64 `json:"cat_limit"`
ClustersLimit int64 `json:"clusters_limit"`
MiscLimit int64 `json:"misc_limit"`
UserLimit int64 `json:"user_limit"`
PermissionLimit int64 `json:"permission_limit"`
AnalyticsLimit int64 `json:"analytics_limit"`
RulesLimit int64 `json:"rules_limit"`
TemplatesLimit int64 `json:"templates_limit"`
SuggestionsLimit int64 `json:"suggestions_limit"`
StreamsLimit int64 `json:"streams_limit"`
AuthLimit int64 `json:"auth_limit"`
FunctionsLimit int64 `json:"functions_limit"`
ReactiveSearchLimit int64 `json:"reactivesearch_limit"`
}

// Options is a function type used to define a permission's properties.
Expand Down Expand Up @@ -468,6 +469,8 @@ func (p *Permission) GetLimitFor(c category.Category) (int64, error) {
return p.Limits.StreamsLimit, nil
case category.Functions:
return p.Limits.FunctionsLimit, nil
case category.ReactiveSearch:
return p.Limits.ReactiveSearchLimit, nil
default:
return -1, fmt.Errorf(`we do not rate limit "%s" category`, c)
}
Expand Down Expand Up @@ -584,6 +587,10 @@ func (p *Permission) GetPatch(rolePatched bool) (map[string]interface{}, error)
limits["functions_limit"] = p.Limits.FunctionsLimit
}

if p.Limits.ReactiveSearchLimit != 0 {
limits["reactivesearch_limit"] = p.Limits.ReactiveSearchLimit
}

patch["limits"] = limits
}
if p.Description != "" {
Expand Down
30 changes: 30 additions & 0 deletions model/queryid/queryid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package queryid

import (
"context"

"github.com/appbaseio/arc/errors"
)

type contextKey string

// ctxKey is a key against which a slice of queryids are stored in the context.
const ctxKey = contextKey("queryid")

// NewContext returns a new context with the given queryids.
func NewContext(ctx context.Context, queryids []string) context.Context {
return context.WithValue(ctx, ctxKey, queryids)
}

// FromContext retrieves the slice of queryids stored against the queryid.CtxKey from the context.
func FromContext(ctx context.Context) ([]string, error) {
ctxQueryIds := ctx.Value(ctxKey)
if ctxQueryIds == nil {
return nil, errors.NewNotFoundInContextError("queryid")
}
reqQueryIds, ok := ctxQueryIds.([]string)
if !ok {
return nil, errors.NewInvalidCastError("ctxQueryIds", "[]string")
}
return reqQueryIds, nil
}
1 change: 1 addition & 0 deletions model/user/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var (
category.Templates,
category.Suggestions,
category.Functions,
category.ReactiveSearch,
category.Auth,
}

Expand Down
5 changes: 5 additions & 0 deletions plugins/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,8 @@ func (a *Auth) Routes() []plugins.Route {
func (a *Auth) ESMiddleware() []middleware.Middleware {
return make([]middleware.Middleware, 0)
}

// Default empty middleware array function
func (a *Auth) RSMiddleware() []middleware.Middleware {
return make([]middleware.Middleware, 0)
}
34 changes: 18 additions & 16 deletions plugins/auth/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var adminCategories = []category.Category{
category.Suggestions,
category.Auth,
category.Functions,
category.ReactiveSearch,
}

var adminOps = []op.Operation{
Expand All @@ -36,22 +37,23 @@ var adminOps = []op.Operation{
}

var defaultAdminLimits = permission.Limits{
IPLimit: 7200,
DocsLimit: 30,
SearchLimit: 30,
IndicesLimit: 30,
CatLimit: 30,
ClustersLimit: 30,
MiscLimit: 30,
UserLimit: 30,
PermissionLimit: 30,
AnalyticsLimit: 30,
RulesLimit: 30,
TemplatesLimit: 30,
SuggestionsLimit: 30,
StreamsLimit: 30,
AuthLimit: 30,
FunctionsLimit: 30,
IPLimit: 7200,
DocsLimit: 30,
SearchLimit: 30,
IndicesLimit: 30,
CatLimit: 30,
ClustersLimit: 30,
MiscLimit: 30,
UserLimit: 30,
PermissionLimit: 30,
AnalyticsLimit: 30,
RulesLimit: 30,
TemplatesLimit: 30,
SuggestionsLimit: 30,
StreamsLimit: 30,
AuthLimit: 30,
FunctionsLimit: 30,
ReactiveSearchLimit: 30,
}

var createPermissionResponse = map[string]interface{}{
Expand Down
6 changes: 4 additions & 2 deletions plugins/auth/main/auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import "github.com/appbaseio/arc/plugins/auth"
import "github.com/appbaseio/arc/plugins"
import (
"github.com/appbaseio/arc/plugins"
"github.com/appbaseio/arc/plugins/auth"
)

var PluginInstance plugins.Plugin = auth.Instance()
Loading

0 comments on commit 1d5a118

Please sign in to comment.