diff options
| -rw-r--r-- | .travis.yml | 5 | ||||
| -rw-r--r-- | README.md | 14 | ||||
| -rw-r--r-- | api/hived.postman_collection.json | 32 | ||||
| -rw-r--r-- | api/swagger.yaml | 56 | ||||
| -rw-r--r-- | docker-compose-travis.yaml | 2 | ||||
| -rw-r--r-- | docker-compose.yaml | 2 | ||||
| -rw-r--r-- | hived.go | 74 | ||||
| -rwxr-xr-x | test/endpoints.sh | 4 | 
8 files changed, 163 insertions, 26 deletions
| diff --git a/.travis.yml b/.travis.yml index 772421d..f0314d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@  language: go +go: +  - 1.15  env:    matrix:    - DOCKER_COMPOSE_VERSION=1.25.0 @@ -11,5 +13,6 @@ services:  before_install:  - docker pull redis:6.2-alpine  install: -- docker build -t hived ./ && docker-compose -f ./docker-compose-travis.yaml up -d +# - docker build -t hived ./ && docker-compose -f ./docker-compose-travis.yaml up -d  # - "./test/endpoints.sh" +  - go build @@ -1,9 +1,10 @@  [](https://travis-ci.org/terminaldweller/hived)  # hived -`hived` is the second version of my personal cryptocurrency server.<br/> -hived is currently using redis as its DB because its tiny and fast.<br/> -It sends notifications through telegram.<br/> +`hived` is the second version of my personal cryptocurrency server:<br/> +* hived is currently using redis as its DB because its tiny and fast.<br/> +* It sends notifications through telegram.<br/> +  Currently it has 4 endpoint:<br/>  ### /price @@ -12,7 +13,8 @@ Lets you ask for the price of the currency. You can determine the currency the v  ### /pair  Takes in a pair of currencies and a multiplier. Determines and returns the ratio.<br/> -### /addalert +### /alert +#### POST  Takes in a name and a math expression containing the names of the currencies. Checks the expression periodically. Sends a message over telegram when the expression holds true.<br/>  The expression's result must be boolean. As an example:<br/>  ```Go @@ -21,6 +23,8 @@ ETH*60/(DOGE*300000) < 4.  ```  You can have as many parameters as you like. The requests for the crypto prices are all turned into individual goroutines so it's fast.<br/>  The expression evaluation is powered by [govaluate](https://github.com/Knetic/govaluate). So for a set of rules and what you can and cannot do please check the documentation over there.<br/> +#### DELETE +Deletes the key from the DB so you will no longer receive updates.<br/>  ### /ex  Gets the list of currencies that are available to be traded.<br/> @@ -51,3 +55,5 @@ You can find the swagger and postman docs under `/api`.<br/>  ## TODO  * fix travis  * add unit tests +* fix `hived -help` crashing +* haproxy-ssl-termination diff --git a/api/hived.postman_collection.json b/api/hived.postman_collection.json index 3cab1e7..c6e3121 100644 --- a/api/hived.postman_collection.json +++ b/api/hived.postman_collection.json @@ -51,14 +51,40 @@  			"response": []  		},  		{ -			"name": "addalert", +			"name": "alert-post",  			"request": {  				"method": "GET",  				"header": [],  				"url": ""  			},  			"response": [] +		}, +		{ +			"name": "alert-delete", +			"request": { +				"method": "GET", +				"header": [], +				"url": "" +			}, +			"response": [] +		}, +		{ +			"name": "ex", +			"request": { +				"method": "GET", +				"header": [], +				"url": "" +			}, +			"response": [] +		}, +		{ +			"name": "health", +			"request": { +				"method": "GET", +				"header": [], +				"url": null +			}, +			"response": []  		} -	], -	"protocolProfileBehavior": {} +	]  }
\ No newline at end of file diff --git a/api/swagger.yaml b/api/swagger.yaml index 9100e82..fb59e08 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -70,7 +70,7 @@ paths:                  properties:                    ratio:                      type: number -  /addalerts: +  /alerts:      post:        description: Add alerts to the alertmanager's list        requestBody: @@ -99,3 +99,57 @@ paths:                      type: string                    isSuccessful:                      type: boolean +    delete: +      description: Remove an alert from alertmanager's list +      parameters: +        - name : id +          in: query +          description: the name of the alert that should be deleted +          schema: +            type: string +      responses: +        '200': +          description: successful delete +          content: +            application/json: +              schema: +                type: object +                properties: +                  err: +                    type: string +                  isSuccessful: +                    type: string +  /ex: +    get: +      description: Returns the list of currencies that are available for trade +      responses: +        '200': +          description: seccussful update +          content: +            application/json: +              schema: +                type: object +                properties: +                  err: +                    type: string +                  isSuccessful: +                    type: boolean +                  tradaeble: +                    type: array +                    items: +                      type: string +  /health: +    get: +      description: Returns the health status of hived +      responses: +        '200': +          description: successful response +          content: +            application/json: +              schema: +                type: object +                properties: +                  isOK: +                    type: boolean +                  Err: +                    type: string diff --git a/docker-compose-travis.yaml b/docker-compose-travis.yaml index 6d1a06d..a5263e0 100644 --- a/docker-compose-travis.yaml +++ b/docker-compose-travis.yaml @@ -11,7 +11,7 @@ services:        - "8008:8008"      depends_on:        - redis -    entrypoint: /hived/docker-entrypoint.sh +    entrypoint: /hived/hived    redis:      image: redis:6.2-alpine      networks: diff --git a/docker-compose.yaml b/docker-compose.yaml index 0b33516..8a404a1 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -30,8 +30,6 @@ services:  networks:    hivednet:      driver: bridge -  routenet: -    driver: bridge  secrets:    tg_bot_token:      file: ./tgtoken @@ -124,10 +124,6 @@ func sendGetToCryptoCompare(  	errChan <- errorChanStruct{hasError: false, err: nil}  } -//TODO -func healthHandler(w http.ResponseWriter, r *http.Request) { -} -  func priceHandler(w http.ResponseWriter, r *http.Request) {  	if r.Method != "GET" {  		http.Error(w, "Method is not supported.", http.StatusNotFound) @@ -417,11 +413,7 @@ type addAlertJSONType struct {  	Expr string `json:"expr"`  } -func addAlertHandler(w http.ResponseWriter, r *http.Request) { -	if r.Method != "POST" { -		http.Error(w, "Method is not supported.", http.StatusNotFound) -	} - +func handleAlertPost(w http.ResponseWriter, r *http.Request) {  	bodyBytes, err := ioutil.ReadAll(r.Body)  	if err != nil {  		log.Printf(err.Error()) @@ -429,7 +421,6 @@ func addAlertHandler(w http.ResponseWriter, r *http.Request) {  	var bodyJSON addAlertJSONType  	json.Unmarshal(bodyBytes, &bodyJSON) -	fmt.Println(bodyJSON)  	if bodyJSON.Name == "" || bodyJSON.Expr == "" {  		json.NewEncoder(w).Encode(map[string]interface{}{ @@ -459,6 +450,54 @@ func addAlertHandler(w http.ResponseWriter, r *http.Request) {  	}  } +func handleAlertDelete(w http.ResponseWriter, r *http.Request) { +	var Id string +	params := r.URL.Query() +	for key, value := range params { +		switch key { +		case "Id": +			Id = value[0] +		default: +			log.Error().Err(errors.New("bad parameters for the crypto endpoint.")) +		} +	} + +	if Id == "" { +		json.NewEncoder(w).Encode(map[string]interface{}{ +			"isSuccessful": false, +			"error":        "Id parameter is not valid."}) +		log.Fatal().Err(errors.New("not all parameters are valid.")) +		return +	} + +	rdb := redis.NewClient(&redis.Options{ +		Addr:     *redisAddress, +		Password: *redisPassword, +		DB:       int(*redisDB), +	}) +	ctx := context.Background() + +	rdb.Del(ctx, Id) +	setKey := "alert:" + Id +	rdb.SRem(ctx, "alertkeys", setKey) + +	json.NewEncoder(w).Encode(struct { +		IsSuccessful bool   `json:"isSuccessful"` +		Err          string `json:"err"` +	}{IsSuccessful: true, Err: ""}) +} + +func alertHandler(w http.ResponseWriter, r *http.Request) { +	if r.Method == "POST" { +		handleAlertPost(w, r) +	} else if r.Method == "DELETE" { +		handleAlertDelete(w, r) +	} else { +		http.Error(w, "Method is not supported.", http.StatusNotFound) +	} + +} +  func exHandler(w http.ResponseWriter, r *http.Request) {  	if r.Method != "GET" {  		http.Error(w, "Method is not supported.", http.StatusNotFound) @@ -521,11 +560,22 @@ func exHandler(w http.ResponseWriter, r *http.Request) {  	json.NewEncoder(w).Encode(responseUnmarshalled)  } +func healthHandler(w http.ResponseWriter, r *http.Request) { +	if r.Method != "GET" { +		http.Error(w, "Method is not supported.", http.StatusNotFound) +	} + +	json.NewEncoder(w).Encode(struct { +		IsOK bool   `json:"isOK"` +		Err  string `json:"err"` +	}{IsOK: true, Err: ""}) +} +  func startServer() {  	http.HandleFunc("/health", healthHandler)  	http.HandleFunc("/price", priceHandler)  	http.HandleFunc("/pair", pairHandler) -	http.HandleFunc("/addalert", addAlertHandler) +	http.HandleFunc("/alert", alertHandler)  	http.HandleFunc("/ex", exHandler)  	if err := http.ListenAndServe(":"+*flagPort, nil); err != nil { @@ -539,7 +589,7 @@ func setupLogging() {  func main() {  	setupLogging() -	go runTgBot() +	// go runTgBot()  	go alertManager()  	startServer()  } diff --git a/test/endpoints.sh b/test/endpoints.sh index 214b1c7..11282bb 100755 --- a/test/endpoints.sh +++ b/test/endpoints.sh @@ -5,7 +5,7 @@ set -x  sleep 5  curl -X GET http://localhost:8008/price?name=CAKE&unit=USD  curl -X GET http://localhost:8008/pair?one=ETH&two=CAKE&multiplier=4.0 -curl -X POST -H "Content-Type: application/json" -d '{"name":"alert1", "expr":"ETH>CAKE"}' http://localhost:8008/addalert +curl -X POST -H "Content-Type: application/json" -d '{"name":"alert1", "expr":"ETH>CAKE"}' http://localhost:8008/alert  # curl -X GET http://127.0.0.1:8008/price?name=CAKE&unit=USD  # curl -X GET http://127.0.0.1:8008/pair?one=ETH&two=CAKE&multiplier=4.0 -# curl -X POST -H "Content-Type: application/json" -d '{"name":"alert1", "expr":"ETH>CAKE"}' http://127.0.0.1:8008/addalert +# curl -X POST -H "Content-Type: application/json" -d '{"name":"alert1", "expr":"ETH>CAKE"}' http://127.0.0.1:8008/alert | 
