Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
heartbeats, ssl, constants
  • Loading branch information
wrr14001 committed Feb 25, 2019
1 parent c1a8b8d commit 2ef9a94
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 19 deletions.
16 changes: 16 additions & 0 deletions constants.go
@@ -0,0 +1,16 @@
package main

const (
// Gateway addresses
dataEndpoint = "https://sd5-endpoint.engr.uconn.edu:48820/data"
heartbeatEndpoint = "https://sd5-endpoint.engr.uconn.edu:48820/heartbeat"

// Header constants
headerUUID = "uuid"
headerTimestamp = "time"

// Time (in seconds) to wait between performing read/send operations
dataReadPeriod = 1
dataSendPeriod = 10
heartbeatPeriod = 10
)
25 changes: 25 additions & 0 deletions rootCA.pem
@@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIERzCCAy+gAwIBAgIJAOmiqMfsrBs/MA0GCSqGSIb3DQEBCwUAMIG5MQswCQYD
VQQGEwJVUzEUMBIGA1UECAwLQ29ubmVjdGljdXQxDzANBgNVBAcMBlN0b3JyczEi
MCAGA1UECgwZVW5pdmVyc2l0eSBvZiBDb25uZWN0aWN1dDEhMB8GA1UECwwYQ1NF
IFNlbmlvciBEZXNpZ24gVGVhbSA1MRUwEwYDVQQDDAxzZDUtZW5kcG9pbnQxJTAj
BgkqhkiG9w0BCQEWFndpbGxpYW0ucmVpZEB1Y29ubi5lZHUwHhcNMTkwMjIwMTQz
ODI0WhcNMjMwMjE5MTQzODI0WjCBuTELMAkGA1UEBhMCVVMxFDASBgNVBAgMC0Nv
bm5lY3RpY3V0MQ8wDQYDVQQHDAZTdG9ycnMxIjAgBgNVBAoMGVVuaXZlcnNpdHkg
b2YgQ29ubmVjdGljdXQxITAfBgNVBAsMGENTRSBTZW5pb3IgRGVzaWduIFRlYW0g
NTEVMBMGA1UEAwwMc2Q1LWVuZHBvaW50MSUwIwYJKoZIhvcNAQkBFhZ3aWxsaWFt
LnJlaWRAdWNvbm4uZWR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
sa79VMjTVCegD+r+nF/vJJwXWAB55ZqoG0tsuntL3gp4LhY8CelYczltL2HwwAG2
YMxdo1TTvBxSn/BHhE2h0gamlooCGMEeh+c8/MAjwkeHGH8CT9ywNT7hzmHwbDLW
SIwO1V9rHJpeiC7aXcI3cqR5kS+zine3m2GgQ2LAW0vDpmNYIjJLz3GmQAeTFLnp
TKIQQqGcR1SiosCnMmBVKLLTXyE/blhuqdGJi61LI7YfhAujX4yJISHzdn9GZmQT
G/kKHlva3Ub7tU0gkzX24tB/x4OZDz5eCLTNhgzx+r5VTpDfipSQoSaNSh7lFUU0
kg/qv0cDmUy00Tea+zo5BwIDAQABo1AwTjAdBgNVHQ4EFgQUABSQnNbFjHULtSGD
UTJb2GKTX8kwHwYDVR0jBBgwFoAUABSQnNbFjHULtSGDUTJb2GKTX8kwDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAW4KiJLtjpzDiWZoPNKRYvFDyaZ7O
oNjWn3bPF8fWO//sQgy4o3fZE9LwporZ3Vz9uAJi1mGS3d/r0kPJi/i3pqNsd2hc
PpSHQS+dxgiB6JXDJkQjoSwGiBj4LXOCbeTcgxGt3Yj5lQeO41lv4Rw7n52IbeDx
+0QmK2/DpCjL2jHv/u9HW1V8ZzT/CJ0b9xNmV9TJHO0uJfVnBIWMU9FN4XuRoElU
md7ym3c5fGWvK7UKZn/Z4jUFvcMr/tpHkQMXtE2vzNvGj504Cx/XaTuGOnnMPUAG
LjTQnTEPhck4TXfNZ/BL6gLx+laXxXZBpVyYooVv3cx787SnsIIyB9H17g==
-----END CERTIFICATE-----
95 changes: 76 additions & 19 deletions server.go
Expand Up @@ -2,20 +2,45 @@ package main

import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"strconv"
"time"
)

type gatewayClient struct {
client *http.Client
}

func main() {
rootCAs := x509.NewCertPool() // Initialize a cert pool
rootCert, _ := ioutil.ReadFile("rootCA.pem") // Read our root CA cert

if ok := rootCAs.AppendCertsFromPEM(rootCert); !ok {
fmt.Printf("Error adding gateway cert")
}

config := &tls.Config{RootCAs: rootCAs,} // Trust our root CA

tr := &http.Transport{TLSClientConfig: config,}
client := gatewayClient{&http.Client{Transport: tr}}

dataReadChan := make(chan map[string]StampedReading) // Channel to handle data readings
dataBuffer := make(map[string][]StampedReading) // Map to store readings in until they are sent

go dataReadLoop(dataReadChan) // Start our async read loop
dataSendTick := time.NewTicker(time.Second * 10) // Ticker to send data
go dataReadLoop(dataReadChan) // Start our async read loop
dataSendTick := time.NewTicker(time.Second * dataSendPeriod) // Ticker to send data
heartbeatTick := time.NewTicker(time.Second * heartbeatPeriod) // Ticker to send heartbeats

if err := client.sendHeartbeat(); err != nil {
fmt.Printf("Error sending startup heartbeat: %v\n", err)
}

// Non-blocking channel reads
for {
Expand All @@ -37,16 +62,24 @@ func main() {
case <-dataSendTick.C:
// Time to send some data
if len(dataBuffer) > 0 { // Only send if we have data
if err := sendData(dataBuffer); err != nil { // Something went wrong
if err := client.sendData(dataBuffer); err != nil { // Something went wrong
fmt.Printf("Error sending data: %v\n", err)
} else { // Data sent, clear the map
fmt.Println("Sent data")
dataBuffer = make(map[string][]StampedReading)
}
} else { // There was no data to send
fmt.Println("Got data send signal but buffer is empty")
// TODO: manage the map so that it doesn't run out of memory and kill everything if we don't send data
}

case <-heartbeatTick.C:
// Send a heartbeat
if err := client.sendHeartbeat(); err != nil {
fmt.Printf("Error sending heartbeat: %v\n", err)
} else {
fmt.Println("Sent heartbeat")
}
}
}
}
Expand Down Expand Up @@ -74,42 +107,66 @@ func readData() map[string]StampedReading {
}
}

func sendData(data map[string][]StampedReading) error {
func (client *gatewayClient) sendData(data map[string][]StampedReading) error {

jsonStr, err := json.Marshal(data) // Dump our data map into a json string
if err != nil {
return err
}

url := "http://localhost:8081/data"
jsonStr, err := json.Marshal(data)
req, err := http.NewRequest("POST", dataEndpoint, bytes.NewBuffer(jsonStr)) // Create our request
if err != nil {
fmt.Printf("Error marshalling data: %v\n", err)
return err
}

fmt.Printf("Sending json: %v\n", string(jsonStr))
fillHeader(req) // Get id and timestamp

resp, err := client.client.Do(req) // Do the request
if err != nil {
return err
}

defer func() {
if err := resp.Body.Close(); err != nil { // Honestly not sure what this is for
fmt.Printf("Error: %v\n", err)
}
}()

if resp.StatusCode < 200 || resp.StatusCode >= 300 { // Make sure it was successful
return errors.New(fmt.Sprintf("Received a non-200 response: %v\n", resp.StatusCode))
}

return nil
}

func (client *gatewayClient) sendHeartbeat() error {
req, err := http.NewRequest("GET", heartbeatEndpoint, nil) // Send to heartbeat endpoint
if err != nil {
return err
}

req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
fillHeader(req)
fillHeader(req) // Get id and timestamp

client := &http.Client{}
resp, err := client.Do(req)
resp, err := client.client.Do(req) // Do it
if err != nil {
return err
}

defer func() {
if err := resp.Body.Close(); err != nil {
fmt.Printf("Error: %v", err)
if err := resp.Body.Close(); err != nil { // This thing again
fmt.Printf("Error: %v\n", err)
}
}()

fmt.Println("response Status:", resp.Status)
if resp.StatusCode != 200 {
fmt.Printf("Received a non-200 response: %v\n", resp.StatusCode)
if resp.StatusCode < 200 || resp.StatusCode >= 300 { // Make sure it was successful
return errors.New(fmt.Sprintf("Received a non-200 response: %v\n", resp.StatusCode))
}

return nil
}

func fillHeader(req *http.Request) { // Sets the uuid and timestamp for a request
req.Header.Set("Content-Type", "application/json")
req.Header.Set("uuid", "0000001bcd3f") // TODO: get this from somewhere
req.Header.Set("time", strconv.FormatInt(time.Now().Unix(), 10))
req.Header.Set(headerUUID, "0000001bcd3f") // TODO: get this from somewhere
req.Header.Set(headerTimestamp, strconv.FormatInt(time.Now().Unix(), 10))
}

0 comments on commit 2ef9a94

Please sign in to comment.