You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
keyboard-reader/rest.go

171 lines
3.3 KiB

package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"strings"
"sync"
"time"
)
const timeout = 1 * time.Second
type MonitorIdTag struct {
ConnectorId uint `json:"connectorId"`
IdTag string `json:"idTag"`
}
type ResponseEntity struct {
Timestamp *time.Time `json:"timestamp"`
Status uint `json:"status"`
Error *string `json:"error"`
Path *string `json:"path"`
}
type RestInterface interface {
Send(id rune)
}
type rest struct {
connectorId uint
url string
timeout time.Duration
mutex sync.Mutex
timer *time.Timer
sb strings.Builder
nospace bool
}
func NewRest(connectorId uint, url string, timeout time.Duration, nospace bool) RestInterface {
r := rest{connectorId: connectorId, url: url, timeout: timeout, nospace: nospace}
return &r
}
func (c *rest) Send(r rune) {
c.mutex.Lock()
defer c.mutex.Unlock()
if !(c.nospace && r == ' ') {
c.sb.WriteRune(r)
}
if c.timer != nil {
c.timer.Reset(timeout)
} else {
f := func() {
s := c.sb.String()
log.Printf("Sent '%s'", s)
go c.send(s)
c.sb.Reset()
}
c.timer = time.AfterFunc(timeout, f)
}
}
func (c *rest) send(id string) {
tag := &MonitorIdTag{IdTag: id, ConnectorId: c.connectorId}
//if c.connectorId > 0 {
// tag.ConnectorId = &c.connectorId
//}
var b []byte
var err error
var request *http.Request
var response *http.Response
if b, err = json.Marshal(tag); err != nil {
log.Printf("Can't marschal request: %e\n", err)
return
}
ctx, _ := context.WithTimeout(context.Background(), c.timeout)
byteReader := bytes.NewReader(b)
if request, err = http.NewRequestWithContext(ctx, "POST", c.url, byteReader); err != nil {
log.Printf("Can't build new request: %e\n", err)
return
}
request.Header.Add("Content-Type", "application/json")
if response, err = http.DefaultClient.Do(request); err != nil {
log.Printf("Error while rerforming request: %e\n", err)
return
}
switch response.StatusCode {
case 200:
log.Printf("Result OK for id '%s'\n", id)
case 401:
log.Printf("Result UNAUTHORIZED for id '%s'\n", id)
default:
log.Printf("Recieve non sucess status code '%d' for id '%s'\n", response.StatusCode, id)
}
if response.ContentLength == 0 {
log.Println("Response body empty")
return
}
if b, err = io.ReadAll(response.Body); err != nil {
log.Printf("Can't read replay body: %e\n", err)
return
}
if err = response.Body.Close(); err != nil {
log.Printf("Error while closing response body: %e\n", err)
return
}
entity := &ResponseEntity{}
if err = json.Unmarshal(b, entity); err != nil {
log.Printf("Can't unmarschal response body: %e\n", err)
return
}
log.Printf("ResponseEntity: %v\n", entity)
}
func (r *ResponseEntity) String() string {
var sb strings.Builder
if r.Path != nil {
sb.WriteString("path = '")
sb.WriteString(*r.Path)
sb.WriteString("'")
}
if r.Error != nil {
if sb.Len() > 0 {
sb.WriteString(", ")
}
sb.WriteString("error = '")
sb.WriteString(*r.Error)
sb.WriteString("'")
}
if r.Timestamp != nil {
if sb.Len() > 0 {
sb.WriteString(", ")
}
sb.WriteString("timestamp = '")
sb.WriteString(r.Timestamp.String())
sb.WriteString("'")
}
if sb.Len() > 0 {
sb.WriteString(", ")
}
sb.WriteString("status = ")
sb.WriteString(fmt.Sprint(r.Status))
return sb.String()
}