diff options
-rw-r--r-- | db.go | 44 | ||||
-rw-r--r-- | db_test.go | 69 | ||||
-rw-r--r-- | environment.go | 75 | ||||
-rw-r--r-- | environment_test.go | 42 | ||||
-rw-r--r-- | go.mod | 6 | ||||
-rw-r--r-- | go.sum | 6 | ||||
-rw-r--r-- | main.go | 31 | ||||
-rw-r--r-- | main_test.go | 16 | ||||
-rw-r--r-- | metrics.go | 57 | ||||
-rw-r--r-- | metrics_test.go | 34 | ||||
-rw-r--r-- | processStars.go | 101 | ||||
-rw-r--r-- | processStars_test.go | 130 |
12 files changed, 611 insertions, 0 deletions
diff --git a/db.go b/db.go new file mode 100644 index 0000000..164984a --- /dev/null +++ b/db.go @@ -0,0 +1,44 @@ +package main + +import ( + "database/sql" + "fmt" + "log" +) + +func connectToDatabase() { + log.Println("[Database] Initializing the database connection") + db = connectToDB() + db.SetMaxOpenConns(75) + pingDB() +} + +// connectToDB returns a pointer to an sql database writing to the database +func connectToDB() *sql.DB { + //connStr := fmt.Sprintf("user=%s dbname=%s sslmode=%s", DBUSER, DBNAME, DBSSLMODE) + connStr := fmt.Sprintf("host=%s port=%d user=%s "+ + "password=%s dbname=%s sslmode=disable", + DBHOST, DBPORT, DBUSER, DBPASSWD, DBNAME) + db := dbConnect(connStr) + return db +} + +// dbConnect connects to a PostgreSQL database +func dbConnect(connStr string) *sql.DB { + // connect to the database + db, err := sql.Open("postgres", connStr) + if err != nil { + log.Fatalf("[ E ] connection: %v", err) + } + + return db +} + +func pingDB() { + // ping the db + err := db.Ping() + if err != nil { + panic(err) + } + log.Println("[ ] Done Pinging the DB") +} diff --git a/db_test.go b/db_test.go new file mode 100644 index 0000000..033cd6d --- /dev/null +++ b/db_test.go @@ -0,0 +1,69 @@ +package main + +import ( + "database/sql" + "reflect" + "testing" +) + +func Test_connectToDatabase(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + connectToDatabase() + }) + } +} + +func Test_connectToDB(t *testing.T) { + tests := []struct { + name string + want *sql.DB + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := connectToDB(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("connectToDB() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_dbConnect(t *testing.T) { + type args struct { + connStr string + } + tests := []struct { + name string + args args + want *sql.DB + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := dbConnect(tt.args.connStr); !reflect.DeepEqual(got, tt.want) { + t.Errorf("dbConnect() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_pingDB(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pingDB() + }) + } +} diff --git a/environment.go b/environment.go new file mode 100644 index 0000000..e5baf2e --- /dev/null +++ b/environment.go @@ -0,0 +1,75 @@ +package main + +import ( + "flag" + "log" + "os" + "strconv" +) + +func getEnvironment() { + log.Println("[environment] Initializing the environment") + getFlags() + getEnvironmentVars() +} + +func getEnvironmentVars() { + log.Println("[ ] Getting the environment variables...") + + // get the data that should be used to connect to the database + + DISTRIBUTORURL = os.Getenv("DISTRIBUTORURL") + if DISTRIBUTORURL == "" { + DISTRIBUTORURL = "localhost:8081" + } + + METRICBUNDLERURL = os.Getenv("METRICBUNDLERURL") + if METRICBUNDLERURL == "" { + METRICBUNDLERURL = "metrics-bundler.nbg1.emile.space" + } + + DBURL = os.Getenv("DBURL") + if DBURL == "" { + DBURL = "postgresql.docker.localhost" + } + + // get the data that should be used to connect to the database + DBUSER = os.Getenv("DBUSER") + if DBUSER == "" { + DBUSER = "postgres" + } + + DBPASSWD = os.Getenv("DBPASSWD") + if DBPASSWD == "" { + DBPASSWD = "" + } + + DBPORT, _ := strconv.ParseInt(os.Getenv("DBPORT"), 10, 64) + if DBPORT == 0 { + DBPORT = 5432 + } + + DBNAME = os.Getenv("DBNAME") + if DBNAME == "" { + DBNAME = "postgres" + } + + log.Println("--------------------") + log.Printf("DBURL: %s", DBHOST) + log.Printf("DBUSER: %s", DBUSER) + log.Printf("DBPASSWD: %s", DBPASSWD) + log.Printf("DBPORT: %d", DBPORT) + log.Printf("DBPROJECTNAME: %s", DBNAME) + log.Println("--------------------") + log.Printf("DISTRIBUTORURL: %s", DISTRIBUTORURL) + log.Printf("METRICBUNDLERURL: %s", METRICBUNDLERURL) + log.Println("--------------------") +} + +func getFlags() { + // Parse the metricsPusherDelay from the command line. + // If no argument is provided, the delay defaults at 5 seconds + flag.Int64Var(&metricsPusherDelay, "metricsPusherDelay", 5, "The delay (in seconds) between the metric Pushes") + flag.Parse() + log.Println("[ ] Done loading the flags") +} diff --git a/environment_test.go b/environment_test.go new file mode 100644 index 0000000..907bf4e --- /dev/null +++ b/environment_test.go @@ -0,0 +1,42 @@ +package main + +import "testing" + +func Test_getEnvironment(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + getEnvironment() + }) + } +} + +func Test_getEnvironmentVars(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + getEnvironmentVars() + }) + } +} + +func Test_getFlags(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + getFlags() + }) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c95efda --- /dev/null +++ b/go.mod @@ -0,0 +1,6 @@ +module simulator-container-rewrite + +require ( + git.darknebu.la/GalaxySimulator/db-actions v0.0.0-20190320194624-e0d84348f5fa + git.darknebu.la/GalaxySimulator/structs v0.0.0-20190205205735-9dd56b9448e5 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..1302f0f --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +git.darknebu.la/GalaxySimulator/db-actions v0.0.0-20190320194624-e0d84348f5fa h1:Q7u+FQvtpT2cIe8GYXXNEfl38UVl4tt7fUOaw8PjMcI= +git.darknebu.la/GalaxySimulator/db-actions v0.0.0-20190320194624-e0d84348f5fa/go.mod h1:D5fanr1NuL8GqX+Eslmpf0+l9dMNZVabmEoysbDlKW0= +git.darknebu.la/GalaxySimulator/structs v0.0.0-20190205205735-9dd56b9448e5 h1:aEQHEERwdLfRJrXb867wZzRMs1ym+j0zDys3opLWPew= +git.darknebu.la/GalaxySimulator/structs v0.0.0-20190205205735-9dd56b9448e5/go.mod h1:LSDIBBC7IcWERm4wlDAroMpsUP7zJ1yDZFlQnP/UIsQ= +github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= diff --git a/main.go b/main.go new file mode 100644 index 0000000..eae62b0 --- /dev/null +++ b/main.go @@ -0,0 +1,31 @@ +package main + +import "database/sql" + +var ( + metricsPusherDelay int64 = 5 + + DBURL string = "postgresql.docker.localhost" + DISTRIBUTORURL string = "localhost:8081" + METRICBUNDLERURL string = "metrics-bundler.nbg1.emile.space" + + DBHOST = "postgres.docker.localhost" + DBPORT = 5432 + DBUSER = "postgres" + DBPASSWD = "" + DBNAME = "postgres" + DBSSLMODE = "disable" + + db *sql.DB + + metrics map[string]float64 + starsProcessed int64 + theta = 0.5 +) + +func main() { + getEnvironment() + connectToDatabase() + initMetricPusher() + processStars() +} diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..35231c6 --- /dev/null +++ b/main_test.go @@ -0,0 +1,16 @@ +package main + +import "testing" + +func Test_main(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + main() + }) + } +} diff --git a/metrics.go b/metrics.go new file mode 100644 index 0000000..32b7cb2 --- /dev/null +++ b/metrics.go @@ -0,0 +1,57 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "net/url" + "time" +) + +func initMetricPusher() { + log.Println("[metrics] Initializing the metricsPusher") + go metricsPusher(METRICBUNDLERURL, metricsPusherDelay) +} + +func metricsPusher(metricsBundlerURL string, metricsPusherDelay int64) { + log.Printf("[metrics pusher] The metrics pusher was startet, it will push metrics every %d seconds to the metrics-bundler at %s", metricsPusherDelay, metricsBundlerURL) + + // if the metrics map does not exist yet, create it + if len(metrics) == 0 { + metrics = make(map[string]float64) + } + + // define the endpoint URL to where the metrics should be pushed + metricsEndpoint := fmt.Sprintf("http://%s/metrics", metricsBundlerURL) + + // infinite loop posting the metrics every n seconds to the metrics-bundler + for { + log.Println("[metrics pusher] Pushing the metrics...") + + // get all keys and values from all items in the metrics map + for key, value := range metrics { + + // make a POST request to the metrics-bundler + _, err := http.PostForm(metricsEndpoint, + url.Values{ + "key": { + fmt.Sprintf("%v", key), + }, + "value": { + fmt.Sprintf("%v", value), + }, + }) + + // handle potential errors by panicking + if err != nil { + panic(err) + } + + } + + log.Printf("[metrics pusher] Done pushing the metrics. Waiting %d seconds...", metricsPusherDelay) + + // sleep for 5 seconds + time.Sleep(time.Second * time.Duration(metricsPusherDelay)) + } +} diff --git a/metrics_test.go b/metrics_test.go new file mode 100644 index 0000000..3e6a141 --- /dev/null +++ b/metrics_test.go @@ -0,0 +1,34 @@ +package main + +import "testing" + +func Test_initMetricPusher(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + initMetricPusher() + }) + } +} + +func Test_metricsPusher(t *testing.T) { + type args struct { + metricsBundlerURL string + metricsPusherDelay int64 + } + tests := []struct { + name string + args args + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + metricsPusher(tt.args.metricsBundlerURL, tt.args.metricsPusherDelay) + }) + } +} diff --git a/processStars.go b/processStars.go new file mode 100644 index 0000000..1bea11c --- /dev/null +++ b/processStars.go @@ -0,0 +1,101 @@ +package main + +import ( + "fmt" + "git.darknebu.la/GalaxySimulator/db-actions" + "git.darknebu.la/GalaxySimulator/structs" + "io/ioutil" + "log" + "net/http" + "strconv" + "time" +) + +func processStars() { + log.Println("[processStars] Initializing the processing process") + + for { + log.Println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++") + + // print the amount of stars allready processed + printStarsProcessed() + + // get some values such as a starID, + starID := getStarID() + star := getStar(starID) + timestep := getTimestep(starID) + + //force := calcAllForces(star, timestep, theta) + force := structs.Vec2{10, 10} + newStar := calcNewPos(star, force, 1e4) + + insertStar(newStar, timestep+1) + + time.Sleep(5 * time.Second) + } +} + +func printStarsProcessed() { + log.Printf("[ ] Stars processed: %d", starsProcessed) +} + +func getStarID() int64 { + log.Printf("[getStarID] Getting a new starID from the distributor (%s)...", DISTRIBUTORURL) + + log.Println("[getStarID] Preparing the http request") + requestURL := fmt.Sprintf("http://%s/distributor", DISTRIBUTORURL) + resp, err := http.Get(requestURL) + log.Printf("[getStarID] Sent http request to %s\n", requestURL) + defer resp.Body.Close() + if err != nil { + log.Printf("resp: %v", resp) + panic(err) + } + + log.Println("[getStarID] Reading the response body") + body, err := ioutil.ReadAll(resp.Body) + log.Println("[getStarID] Done Reading the response body") + if err != nil { + panic(err) + } + + log.Printf("[getStarID] Got the response: %v", string(body)) + log.Println("[getStarID] Parsing the integer") + starID, parseIntErr := strconv.ParseInt(string(body), 10, 64) + if parseIntErr != nil { + panic(parseIntErr) + } + log.Println("[getStarID] Done parsing the integer") + + return starID +} + +func getStar(starID int64) structs.Star2D { + var star = db_actions.GetStar(db, starID) + return star +} + +func getTimestep(starID int64) int64 { + var timestep = db_actions.GetStarIDTimestep(db, starID) + return timestep +} + +func calcNewPos(star structs.Star2D, force structs.Vec2, timestep float64) structs.Star2D { + star.CalcNewPos(force, timestep) + returnStar := structs.Star2D{ + C: structs.Vec2{ + X: star.C.X, + Y: star.C.Y, + }, + V: structs.Vec2{ + X: force.X, + Y: force.Y, + }, + M: star.M, + } + return returnStar +} + +func insertStar(star structs.Star2D, timestep int64) { + log.Printf("Inserting the star %v into the timestep %d", star, timestep) +} diff --git a/processStars_test.go b/processStars_test.go new file mode 100644 index 0000000..7688cd5 --- /dev/null +++ b/processStars_test.go @@ -0,0 +1,130 @@ +package main + +import ( + "reflect" + "testing" + + "git.darknebu.la/GalaxySimulator/structs" +) + +func Test_processStars(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + processStars() + }) + } +} + +func Test_printStarsProcessed(t *testing.T) { + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + printStarsProcessed() + }) + } +} + +func Test_getStarID(t *testing.T) { + tests := []struct { + name string + want int64 + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getStarID(); got != tt.want { + t.Errorf("getStarID() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_getStar(t *testing.T) { + type args struct { + starID int64 + } + tests := []struct { + name string + args args + want structs.Star2D + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getStar(tt.args.starID); !reflect.DeepEqual(got, tt.want) { + t.Errorf("getStar() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_getTimestep(t *testing.T) { + type args struct { + starID int64 + } + tests := []struct { + name string + args args + want int64 + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getTimestep(tt.args.starID); got != tt.want { + t.Errorf("getTimestep() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_calcNewPos(t *testing.T) { + type args struct { + star structs.Star2D + force structs.Vec2 + timestep float64 + } + tests := []struct { + name string + args args + want structs.Star2D + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := calcNewPos(tt.args.star, tt.args.force, tt.args.timestep); !reflect.DeepEqual(got, tt.want) { + t.Errorf("calcNewPos() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_insertStar(t *testing.T) { + type args struct { + star structs.Star2D + timestep int64 + } + tests := []struct { + name string + args args + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + insertStar(tt.args.star, tt.args.timestep) + }) + } +} |