aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--README.md14
-rw-r--r--api/hived.postman_collection.json32
-rw-r--r--api/swagger.yaml56
-rw-r--r--docker-compose-travis.yaml2
-rw-r--r--docker-compose.yaml2
-rw-r--r--hived.go74
-rwxr-xr-xtest/endpoints.sh4
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
diff --git a/README.md b/README.md
index 77cc7f2..b301084 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,10 @@
[![Build Status](https://travis-ci.org/terminaldweller/hived.svg?branch=main)](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
diff --git a/hived.go b/hived.go
index 90b4b3b..a1cd988 100644
--- a/hived.go
+++ b/hived.go
@@ -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