-
Notifications
You must be signed in to change notification settings - Fork 350
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Include fix #339 * Includes some code for the playground yet it was not yet fixed. * Increased go version to 1.18
- Loading branch information
Showing
61 changed files
with
59,534 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package editor | ||
|
||
import ( | ||
"encoding/base64" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/hyperjumptech/grule-rule-engine/ast" | ||
"github.com/hyperjumptech/grule-rule-engine/builder" | ||
"github.com/hyperjumptech/grule-rule-engine/engine" | ||
"github.com/hyperjumptech/grule-rule-engine/pkg" | ||
mux "github.com/hyperjumptech/hyper-mux" | ||
"io/ioutil" | ||
"net/http" | ||
) | ||
|
||
type JSONData struct { | ||
Name string | ||
JSONData string `json:"jsonText"` | ||
} | ||
|
||
type EvaluateRequest struct { | ||
GrlText string `json:"grlText"` | ||
Input []*JSONData `json:"jsonInput"` | ||
} | ||
|
||
func InitializeEvaluationRoute(router *mux.HyperMux) { | ||
router.AddRoute("/evaluate", http.MethodPost, func(w http.ResponseWriter, r *http.Request) { | ||
bodyBytes, err := ioutil.ReadAll(r.Body) | ||
if err != nil { | ||
w.WriteHeader(http.StatusInternalServerError) | ||
_, _ = w.Write([]byte(fmt.Sprintf("error while reading body stream. got %v", err))) | ||
return | ||
} | ||
evReq := &EvaluateRequest{} | ||
err = json.Unmarshal(bodyBytes, evReq) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
_, _ = w.Write([]byte(fmt.Sprintf("wrong json format. got %v \n\n Json : %s", err, string(bodyBytes)))) | ||
return | ||
} | ||
|
||
dataContext := ast.NewDataContext() | ||
|
||
for _, jd := range evReq.Input { | ||
jsonByte, err := base64.StdEncoding.DecodeString(jd.JSONData) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
_, _ = w.Write([]byte(fmt.Sprintf("json data named %s should be sent using base64. got %v", jd.Name, err))) | ||
return | ||
} | ||
err = dataContext.AddJSON(jd.Name, jsonByte) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
_, _ = w.Write([]byte(fmt.Sprintf("invalid JSON data named %s when add json to context got %v", jd.Name, err))) | ||
return | ||
} | ||
} | ||
|
||
lib := ast.NewKnowledgeLibrary() | ||
rb := builder.NewRuleBuilder(lib) | ||
|
||
grlByte, err := base64.StdEncoding.DecodeString(evReq.GrlText) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
_, _ = w.Write([]byte(fmt.Sprintf("GRL data should be sent using base64. got %v", err))) | ||
return | ||
} | ||
|
||
err = rb.BuildRuleFromResource("Evaluator", "0.0.1", pkg.NewBytesResource(grlByte)) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
_, _ = w.Write([]byte(fmt.Sprintf("invalid GRL : %s", err.Error()))) | ||
return | ||
} | ||
|
||
eng1 := &engine.GruleEngine{MaxCycle: 5} | ||
kb := lib.NewKnowledgeBaseInstance("Evaluator", "0.0.1") | ||
err = eng1.Execute(dataContext, kb) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
_, _ = w.Write([]byte(fmt.Sprintf("Grule Error : %s", err.Error()))) | ||
return | ||
} | ||
|
||
respData := make(map[string]interface{}) | ||
for _, keyName := range dataContext.GetKeys() { | ||
respData[keyName] = dataContext.Get(keyName) | ||
} | ||
|
||
resultBytes, err := json.Marshal(respData) | ||
if err != nil { | ||
w.WriteHeader(http.StatusInternalServerError) | ||
_, _ = w.Write([]byte(fmt.Sprintf("Error marshaling result : %s", err.Error()))) | ||
return | ||
} | ||
|
||
w.Header().Add("Content-Type", "application/json") | ||
w.WriteHeader(http.StatusOK) | ||
_, _ = w.Write(resultBytes) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package editor | ||
|
||
import ( | ||
"context" | ||
mux "github.com/hyperjumptech/hyper-mux" | ||
"github.com/sirupsen/logrus" | ||
"log" | ||
"net/http" | ||
"os" | ||
"os/signal" | ||
"time" | ||
) | ||
|
||
var ( | ||
hmux = mux.NewHyperMux() | ||
) | ||
|
||
func Start() { | ||
InitializeStaticRoute(hmux) | ||
InitializeEvaluationRoute(hmux) | ||
|
||
var wait time.Duration | ||
address := "0.0.0.0:32123" | ||
|
||
logrus.Infof("Starting Editor at http://%s", address) | ||
|
||
srv := &http.Server{ | ||
Addr: address, | ||
WriteTimeout: 10 * time.Second, | ||
ReadTimeout: 10 * time.Second, | ||
IdleTimeout: 10 * time.Second, | ||
Handler: hmux, // Pass our instance of gorilla/mux in. | ||
} | ||
|
||
startTime := time.Now() | ||
|
||
// Run our server in a goroutine so that it doesn't block. | ||
go func() { | ||
if err := srv.ListenAndServe(); err != nil { | ||
log.Println(err) | ||
} | ||
}() | ||
|
||
c := make(chan os.Signal, 1) | ||
// We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C) | ||
// SIGKILL, SIGQUIT or SIGTERM (Ctrl+/) will not be caught. | ||
signal.Notify(c, os.Interrupt) | ||
|
||
// Block until we receive our signal. | ||
<-c | ||
|
||
// Create a deadline to wait for. | ||
ctx, cancel := context.WithTimeout(context.Background(), wait) | ||
defer cancel() | ||
// Doesn't block if no connections, but will otherwise wait | ||
// until the timeout deadline. | ||
srv.Shutdown(ctx) | ||
// Optionally, you could run srv.Shutdown in a goroutine and block on | ||
// <-ctx.Done() if your application should wait for other services | ||
// to finalize based on context cancellation. | ||
dur := time.Now().Sub(startTime) | ||
logrus.Infof("Shutting down. This Satpam been protecting the world for %s", dur.String()) | ||
os.Exit(0) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package editor | ||
|
||
import ( | ||
"embed" | ||
"fmt" | ||
"github.com/hyperjumptech/grule-rule-engine/editor/mime" | ||
mux "github.com/hyperjumptech/hyper-mux" | ||
"github.com/sirupsen/logrus" | ||
"net/http" | ||
"os" | ||
"strings" | ||
) | ||
|
||
//go:embed statics | ||
var fs embed.FS | ||
|
||
var ( | ||
errFileNotFound = fmt.Errorf("file not found") | ||
) | ||
|
||
type FileData struct { | ||
Bytes []byte | ||
ContentType string | ||
} | ||
|
||
func IsDir(path string) bool { | ||
for _, s := range GetPathTree("static") { | ||
if s == "[DIR]"+path { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func GetPathTree(path string) []string { | ||
logrus.Debugf("Into %s", path) | ||
var entries []os.DirEntry | ||
var err error | ||
if strings.HasPrefix(path, "./") { | ||
entries, err = fs.ReadDir(path[2:]) | ||
} else { | ||
entries, err = fs.ReadDir(path) | ||
} | ||
ret := make([]string, 0) | ||
if err != nil { | ||
return ret | ||
} | ||
logrus.Debugf("Path %s %d etries", path, len(entries)) | ||
for _, e := range entries { | ||
if e.IsDir() { | ||
ret = append(ret, "[DIR]"+path+"/"+e.Name()) | ||
ret = append(ret, GetPathTree(path+"/"+e.Name())...) | ||
} else { | ||
ret = append(ret, path+"/"+e.Name()) | ||
} | ||
} | ||
return ret | ||
} | ||
|
||
func GetFile(path string) (*FileData, error) { | ||
bytes, err := fs.ReadFile(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
mimeType, err := mime.MimeForFileName(path) | ||
if err != nil { | ||
return &FileData{ | ||
Bytes: bytes, | ||
ContentType: http.DetectContentType(bytes), | ||
}, nil | ||
} | ||
return &FileData{ | ||
Bytes: bytes, | ||
ContentType: mimeType, | ||
}, nil | ||
} | ||
|
||
func InitializeStaticRoute(router *mux.HyperMux) { | ||
for _, p := range GetPathTree("statics") { | ||
if !strings.HasPrefix(p, "[DIR]") { | ||
path := p[len("statics"):] | ||
router.AddRoute(path, http.MethodGet, StaticHandler(p)) | ||
} | ||
} | ||
|
||
router.AddRoute("/", http.MethodGet, func(writer http.ResponseWriter, request *http.Request) { | ||
writer.Header().Add("Location", "/index.html") | ||
writer.WriteHeader(http.StatusMovedPermanently) | ||
}) | ||
} | ||
|
||
func StaticHandler(path string) func(writer http.ResponseWriter, request *http.Request) { | ||
fData, err := GetFile(path) | ||
if err != nil { | ||
return func(writer http.ResponseWriter, request *http.Request) { | ||
_, _ = writer.Write([]byte(err.Error())) | ||
writer.WriteHeader(http.StatusInternalServerError) | ||
} | ||
} | ||
return func(writer http.ResponseWriter, request *http.Request) { | ||
writer.Header().Add("Content-Type", fData.ContentType) | ||
writer.WriteHeader(http.StatusOK) | ||
_, _ = writer.Write(fData.Bytes) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/hyperjumptech/grule-rule-engine/editor" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
func main() { | ||
logrus.SetLevel(logrus.TraceLevel) | ||
editor.Start() | ||
} |
Oops, something went wrong.