| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 | /* * EliasDB * * Copyright 2016 Matthias Ladkau. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */package v1import (	"encoding/json"	"fmt"	"net/http"	"devt.de/krotik/eliasdb/api"	"devt.de/krotik/eliasdb/eql"	"devt.de/krotik/eliasdb/eql/parser")/*EndpointEql is the eql endpoint URL (rooted). Handles everything under eql/...*/const EndpointEql = api.APIRoot + APIv1 + "/eql/"/*EqlEndpointInst creates a new endpoint handler.*/func EqlEndpointInst() api.RestEndpointHandler {	return &eqlEndpoint{}}/*Handler object for eql operations.*/type eqlEndpoint struct {	*api.DefaultEndpointHandler}/*HandlePOST handles REST calls to transform EQL queries.*/func (e *eqlEndpoint) HandlePOST(w http.ResponseWriter, r *http.Request, resources []string) {	dec := json.NewDecoder(r.Body)	data := make(map[string]interface{})	if err := dec.Decode(&data); err != nil {		http.Error(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)		return	}	// Handle query and ast requests	query, ok1 := data["query"]	ast, ok2 := data["ast"]	if ok1 || ok2 {		res := make(map[string]interface{})		if ok1 {			resast, err := eql.ParseQuery("request", fmt.Sprint(query))			if err != nil {				http.Error(w, err.Error(), http.StatusBadRequest)				return			}			res["ast"] = resast.Plain()		}		if ok2 {			astmap, ok := ast.(map[string]interface{})			if !ok {				http.Error(w, "Plain AST object expected as 'ast' value", http.StatusBadRequest)				return			}			// Try to create a proper AST from plain AST			astnode, err := parser.ASTFromPlain(astmap)			if err != nil {				http.Error(w, err.Error(), http.StatusBadRequest)				return			}			// Now pretty print the AST			ppres, err := parser.PrettyPrint(astnode)			if err != nil {				http.Error(w, err.Error(), http.StatusBadRequest)				return			}			res["query"] = ppres		}		w.Header().Set("content-type", "application/json; charset=utf-8")		json.NewEncoder(w).Encode(res)		return	}	http.Error(w, "Need either a query or an ast parameter", http.StatusBadRequest)}/*SwaggerDefs is used to describe the endpoint in swagger.*/func (e *eqlEndpoint) SwaggerDefs(s map[string]interface{}) {	s["paths"].(map[string]interface{})["/v1/eql"] = map[string]interface{}{		"post": map[string]interface{}{			"summary":     "EQL parser and pretty printer endpoint.",			"description": "The eql endpoint should be used to parse a given EQL query into an Abstract Syntax Tree or pretty print a given Abstract Syntax Tree into an EQL query.",			"consumes": []string{				"application/json",			},			"produces": []string{				"text/plain",				"application/json",			},			"parameters": []map[string]interface{}{				{					"name":        "data",					"in":          "body",					"description": "Query or AST which should be converted.",					"required":    true,					"schema": map[string]interface{}{						"type": "object",						"properties": map[string]interface{}{							"query": map[string]interface{}{								"description": "Query which should be parsed.",								"type":        "string",							},							"ast": map[string]interface{}{								"description": "AST which should be pretty printed.",								"type":        "object",							},						},					},				},			},			"responses": map[string]interface{}{				"200": map[string]interface{}{					"description": "The operation was successful.",					"schema": map[string]interface{}{						"type": "object",						"properties": map[string]interface{}{							"ast": map[string]interface{}{								"description": "The resulting AST if a query was parsed.",								"type":        "object",							},							"query": map[string]interface{}{								"description": "The pretty printed query if an AST was given.",								"type":        "string",							},						},					},				},				"default": map[string]interface{}{					"description": "Error response",					"schema": map[string]interface{}{						"$ref": "#/definitions/Error",					},				},			},		},	}}
 |