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

Feature: API metadata and Execute via LSP #48

Merged
merged 13 commits into from
Sep 8, 2024
52 changes: 52 additions & 0 deletions .github/workflows/internal_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Lama2 Release
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'

jobs:
releases-matrix:
permissions: write-all
name: Release Go Binary
runs-on: ubuntu-latest
strategy:
matrix:
# build and publish in parallel: linux/386, linux/amd64, linux/arm64, windows/386, windows/amd64, darwin/amd64, darwin/arm64
goos: [linux, windows, darwin]
goarch: ["386", amd64, arm64]
exclude:
- goarch: "386"
goos: darwin
- goarch: arm64
goos: windows
steps:
- uses: actions/checkout@v3
- uses: wangyoucao577/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
goversion: "https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz"
binary_name: "l2"
extra_files: LICENSE README.md
ldflags: -X main.version=${{ github.ref_name }}
build_flags: '-tags=cli'
# Separate job for Wasm build
wasm-build:
permissions: write-all
name: Build WebAssembly Binary
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: wangyoucao577/[email protected]
with:
go-version: "https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz"
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: js
goarch: wasm
goversion: "https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz"
binary_name: "l2.wasm"
extra_files: LICENSE README.md
ldflags: -X main.version=${{ github.ref_name }}
build_flags: |
-tags=wasm -a -gcflags="all=-l -wb=false -ldflags="-w -s"
50 changes: 25 additions & 25 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "by-gdb",
"request": "launch",
"name": "Launch(gdb)",
"program": "${fileBasenameNoExtension}",
"programArgs": "examples/0009_processor_basic/0009_processor_basic.l2",
"debuggerArgs": ["--args"],
"cwd": "${workspaceRoot}"
},
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"args": ["-h"]
}
]
}
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "by-gdb",
"request": "launch",
"name": "Launch(gdb)",
"program": "${fileBasenameNoExtension}",
"programArgs": "examples/0009_processor_basic/0009_processor_basic.l2",
"debuggerArgs": ["--args"],
"cwd": "${workspaceRoot}"
},

{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"args": ["-h"]
}
]
}
11 changes: 8 additions & 3 deletions cmdexec/cmdexec.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"errors"
"os"
"strings"
"time"

"github.com/HexmosTech/httpie-go"
"github.com/HexmosTech/lama2/utils"
Expand All @@ -21,13 +22,17 @@ import (
// to stdout.
// Once execution finishes, previous CWD is restored,
// and the command output is returned as a string
func ExecCommand(cmdSlice []string, stdinBody string, apiDir string) (httpie.ExResponse, error) {
func ExecCommand(cmdSlice []string, stdinBody string, apiDir string) (httpie.ExResponse, int64, error) {
oldDir, _ := os.Getwd()
utils.ChangeWorkingDir(apiDir)
start := time.Now()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are checking time http request only ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes the time difference between executing the API request

resp, err := httpie.Lama2Entry(cmdSlice, strings.NewReader(stdinBody))
if err != nil {
return httpie.ExResponse{}, errors.New("Error from API executor: " + err.Error())
return httpie.ExResponse{}, 0, errors.New("Error from API executor: " + err.Error())
}
elapsed := time.Since(start)
utils.ChangeWorkingDir(oldDir)
return resp, nil
responseTime := elapsed.Milliseconds()

return resp, responseTime, nil
}
11 changes: 7 additions & 4 deletions cmdexec/cmdexec.wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"errors"
"fmt"
"os"

"strings"
"time"

"github.com/HexmosTech/httpie-go"
)
Expand All @@ -22,15 +22,18 @@ import (
// to stdout.
// Once execution finishes, previous CWD is restored,
// and the command output is returned as a string
func ExecCommand(cmdSlice []string, stdinBody string, apiDir string) (httpie.ExResponse, error) {
func ExecCommand(cmdSlice []string, stdinBody string, apiDir string) (httpie.ExResponse, int64, error) {
proxyURL := os.Getenv("PROXY_URL")
proxyUserName := os.Getenv("PROXY_USERNAME")
proxyUserPassword := os.Getenv("PROXY_PASSWORD")
allowRedirects := true
start := time.Now()
resp, err := httpie.Lama2Entry(cmdSlice, strings.NewReader(stdinBody), proxyURL, proxyUserName, proxyUserPassword, allowRedirects)
elapsed := time.Since(start)
responseTime := elapsed.Milliseconds()
if err != nil {
fmt.Println("Got error while executing", err)
return httpie.ExResponse{}, errors.New("Error from API executor: " + err.Error())
return httpie.ExResponse{}, 0, errors.New("Error from API executor: " + err.Error())
}
return resp, nil
return resp, responseTime, nil
}
1 change: 0 additions & 1 deletion cmdexec/js.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//go:build cli


package cmdexec

import (
Expand Down
3 changes: 1 addition & 2 deletions cmdexec/js.wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
package cmdexec

import (
"fmt"
"syscall/js"

"github.com/rs/zerolog/log"
)

Expand All @@ -30,7 +30,6 @@ func RunVMCode(jsCode string, vm interface{}) {

// GenerateChainCode takes in an HTTP response body and comes up with some JS code to define the "magic variable" result.
func GenerateChainCode(httpRespBody string) string {
fmt.Println("WW: Value of httpRespBody is",httpRespBody)
code := `try {
result = JSON.parse(String.raw` + "`" + httpRespBody + "`" + `)
console.log("Stored as JSON")
Expand Down
10 changes: 4 additions & 6 deletions cmdgen/cmdgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import (
"github.com/HexmosTech/lama2/lama2cmd"
)

// The assembleCmdString function constructs a httpie
// command string for an HTTP request based on the provided
// The assembleCmdString function constructs a httpie
// command string for an HTTP request based on the provided
// HTTP method, URL, JSON object, headers, and options. It also
// handle multipart and form data.
//
// handle multipart and form data.
func assembleCmdString(httpv string, url string, jsonObj *gabs.Container, headers *gabs.Container, multipart bool, form bool, o *lama2cmd.Opts) ([]string, string) {
command := make([]string, 0)
var files *gabs.Container
Expand Down Expand Up @@ -93,7 +94,6 @@ func assembleCmdString(httpv string, url string, jsonObj *gabs.Container, header
// and finally generates a string representing the generated
// command
func ConstructCommandHelper(parsedInput *gabs.Container) (string, string, *gabs.Container, *gabs.Container, bool, bool) {
fmt.Println("WW parsedInput:", parsedInput.StringIndent("", " "))
httpv := parsedInput.S("verb", "value")
url := parsedInput.S("url", "value")
jsonObj := parsedInput.S("details", "ip_data")
Expand All @@ -105,7 +105,5 @@ func ConstructCommandHelper(parsedInput *gabs.Container) (string, string, *gabs.
multipartBool = true
}
formBool := form != nil
fmt.Println("WW httpv:", httpv.Data().(string))
fmt.Println("WW url:", url.Data().(string))
return httpv.Data().(string), url.Data().(string), jsonObj, headers, multipartBool, formBool
}
2 changes: 1 addition & 1 deletion codegen/codegen.cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func generateConvertedSippet(targetLangLib string, parsedAPI *gabs.Container) st
log.Debug().Str("Processor block incoming block", block.String()).Msg("")
convertedSnippetList = append(convertedSnippetList, snippet)
} else if blockType == "Lama2File" {
harRequest, flag := GetRequestHARString(block,targetLangLib)
harRequest, flag := GetRequestHARString(block, targetLangLib)
snippetArgs := SnippetArgs{}
lang, lib := SplitLangLib(targetLangLib)
snippetArgs.Language = lang
Expand Down
26 changes: 13 additions & 13 deletions codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type SnippetArgs struct {

func GetRequestHARString(block *gabs.Container, targetLang string) (string, int) {
httpv := block.S("verb", "value").String()
httpv = strings.Trim(httpv, `"`)
httpv = strings.Trim(httpv, `"`)
httpv = strings.Trim(httpv, `'`)
url := block.S("url", "value")
flag := preprocessURL(url)
Expand All @@ -28,9 +28,9 @@ func GetRequestHARString(block *gabs.Container, targetLang string) (string, int)
harObj := gabs.New()

if strings.Contains(strings.ToLower(targetLang), "python") || strings.Contains(strings.ToLower(targetLang), "shell") || strings.Contains(strings.ToLower(targetLang), "php") {
httpv = strings.ToUpper(httpv)
}
httpv = strings.ToUpper(httpv)
}

if jsonObj != nil {
postData := gabs.New()
postData.Set("application/json", "mimeType")
Expand Down Expand Up @@ -109,12 +109,12 @@ func preprocessURL(url *gabs.Container) int {
urls := url.String()
flag := 0
fmt.Println("URL:", urls)
urls = strings.Trim(urls, `"`)
urls = strings.Trim(urls, `'`)
urls = strings.Trim(urls, `"`)
urls = strings.Trim(urls, `'`)
fmt.Println("URL Updated:", urls)
if !strings.HasPrefix(urls, "https://") && !strings.HasPrefix(urls, "http://") {
fmt.Println("URL does not start with 'https://' or 'http://'")
newURL := "https://" + urls
fmt.Println("URL does not start with 'https://' or 'http://'")
newURL := "https://" + urls
// if !strings.Contains(newURL, ".com") {
// parts := strings.SplitN(newURL, "://", 2)
// protocol = parts[0] + "://"
Expand All @@ -125,10 +125,10 @@ func preprocessURL(url *gabs.Container) int {
// newURL += ".com"
// }
// }
url.Set(newURL)
flag = 1
}
url.Set(newURL)
flag = 1
}

// Remove the outermost "${}" to isolate the placeholder content
fmt.Print("URL:", urls)
return flag
Expand All @@ -144,7 +144,7 @@ func postprocessURL(convertedSnippet string, flag int) string {
fmt.Println("Error decoding URL:", err)
return convertedSnippet
}
// decodedURL = strings.Replace(decodedURL, `""`, `"`, -1) removed for python
// decodedURL = strings.Replace(decodedURL, `""`, `"`, -1) removed for python
return decodedURL
// return convertedSnippet
}
Expand Down
1 change: 0 additions & 1 deletion codegen/codegen.wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ func generateConvertedSippet(targetLangLib string, parsedAPI *gabs.Container) st
snippetArgs.SnippetCore = snippetcore
fmt.Println("Snippet args:", snippetArgs)
httpsnippetCode := PrepareHTTPSnippetGenerator(snippetArgs)
//fmt.Println("httpsnippetCode:", httpsnippetCode)
convertedSnippet := js.Global().Call("eval", httpsnippetCode)
fmt.Println("convertedSnippet data:", convertedSnippet.String())
// convertedSnippet, err := evaluateJSCode(httpsnippetCode)
Expand Down
2 changes: 0 additions & 2 deletions codegen/codegenwasmgonew
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ func generateConvertedSippet(targetLangLib string, parsedAPI *gabs.Container) st
fmt.Println("Snippet args:", snippetArgs)
fmt.Println("CC: 2.2")
httpsnippetCode := PrepareHTTPSnippetGenerator(snippetArgs)
// fmt.Println("CC: 3. Prepared HTTPSnippet",httpsnippetCode)
// fmt.Println("httpsnippetCode:", httpsnippetCode)
fmt.Println("CC: 3.1 Finished preparation, calling converstion")
convertedSnippet := js.Global().Call("eval", httpsnippetCode)
fmt.Println("CC: 4. Converted httpsnippet",convertedSnippet.String())
Expand Down
31 changes: 25 additions & 6 deletions controller/controller.cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package contoller
import (
"fmt"
"os"
"strconv"

"github.com/HexmosTech/gabs/v2"
"github.com/HexmosTech/httpie-go"
Expand All @@ -23,7 +24,7 @@ import (
"github.com/rs/zerolog/log"
)

func HandleParsedFile(parsedAPI *gabs.Container, o *lama2cmd.Opts, dir string) (httpie.ExResponse, *lama2cmd.Opts) {
func HandleParsedFile(parsedAPI *gabs.Container, o *lama2cmd.Opts, dir string) (httpie.ExResponse, *lama2cmd.Opts, []outputmanager.ResponseTime, []outputmanager.StatusCode, []outputmanager.ContentSize, error) {
vm := cmdexec.GetJSVm()
return HandleParsedFileHelper(parsedAPI, o, dir, vm)
}
Expand Down Expand Up @@ -70,15 +71,22 @@ func Process(version string) {
Msg("Parse Error")
}
log.Debug().Str("Parsed API", parsedAPI.String()).Msg("")
res, out := HandleParsedFile(parsedAPI, o, dir)
res, out, responseTime, statusCodes, contentSizes, err := HandleParsedFile(parsedAPI, o, dir)
if err != nil {
log.Fatal().Str("Type", "Controller").Msg(fmt.Sprint("Error: ", err))
}
if out.Output != "" {
outputmanager.WriteJSONOutput(res, out.Output)
outputmanager.WriteJSONOutput(res, out.Output, responseTime, statusCodes, contentSizes)
}
}

func processBlocks(parsedAPIblocks []*gabs.Container, o *lama2cmd.Opts, dir string) (httpie.ExResponse, *lama2cmd.Opts) {
func processBlocks(parsedAPIblocks []*gabs.Container, o *lama2cmd.Opts, dir string) (httpie.ExResponse, *lama2cmd.Opts, []outputmanager.ResponseTime, []outputmanager.StatusCode, []outputmanager.ContentSize) {
vm := cmdexec.GetJSVm()
var resp httpie.ExResponse
var responseTime []outputmanager.ResponseTime
var statusCode []outputmanager.StatusCode
var contentSize []outputmanager.ContentSize
var timeInMs int64
for i, block := range parsedAPIblocks {
log.Debug().Int("Block num", i).Msg("")
log.Debug().Str("Block getting processed", block.String()).Msg("")
Expand All @@ -87,10 +95,12 @@ func processBlocks(parsedAPIblocks []*gabs.Container, o *lama2cmd.Opts, dir stri
case "processor":
ExecuteProcessorBlock(block, vm)
case "Lama2File":
resp = processLama2FileBlock(block, vm, o, dir)
resp, timeInMs = processLama2FileBlock(block, vm, o, dir)
log.Info().Str("ResponseTime", fmt.Sprintf("%dms", timeInMs)).Msg("")
responseTime, statusCode, contentSize = CalculateMetrics(resp, timeInMs, responseTime, statusCode, contentSize)
}
}
return resp, o
return resp, o, responseTime, statusCode, contentSize
}

func ExecuteRequestorBlockHelper(resp httpie.ExResponse, headersString string, e1 error, vm interface{}) httpie.ExResponse {
Expand All @@ -110,3 +120,12 @@ func ExecuteProcessorBlock(block *gabs.Container, vm interface{}) {
script := b.Data().(string)
cmdexec.RunVMCode(script, vm)
}

func CalculateMetrics(resp httpie.ExResponse, timeInMs int64, responseTime []outputmanager.ResponseTime, statusCodes []outputmanager.StatusCode, contentSizes []outputmanager.ContentSize) ([]outputmanager.ResponseTime, []outputmanager.StatusCode, []outputmanager.ContentSize) {
responseTime = append(responseTime, outputmanager.ResponseTime{Type: "l2block", TimeInMs: timeInMs})
statusCodes = append(statusCodes, outputmanager.StatusCode{Type: "l2block", Status: resp.StatusCode})
sizeInBytes, _ := strconv.Atoi(resp.Headers["Content-Length"])
contentSizes = append(contentSizes, outputmanager.ContentSize{Type: "l2block", SizeInBytes: sizeInBytes})

return responseTime, statusCodes, contentSizes
}
Loading
Loading