Commit ddd54667 authored by Aksel Baardsen's avatar Aksel Baardsen
Browse files

Added errors to most funcs, need proper handling from handlers

parent 2f9d3e7b
......@@ -12,21 +12,23 @@ import (
func Chandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
limit := r.FormValue("limit") // gets the limit, if specified
// unnecessary default limit (gbif API has default of 20)
if len(limit) == 0 {
limit = "5"
}
country, code := pkg.GetCountryByCode(vars["country_identifier"], limit)
c, _ := json.Marshal(country)
country, err := pkg.GetCountryByCode(vars["country_identifier"], limit)
if code == http.StatusOK {
if err == nil {
w.Header().Set("Content-Type", "application/json")
_, err := fmt.Fprintln(w, string(c))
err = json.NewEncoder(w).Encode(&country)
if err != nil {
log.Fatal(err)
}
} else {
w.WriteHeader(http.StatusBadGateway)
_, _ = fmt.Fprintln(w, http.StatusBadGateway)
// need to check error for content before setting header
w.WriteHeader(http.StatusInternalServerError)
_, _ = fmt.Fprintln(w, "An error occured")
}
}
\ No newline at end of file
......@@ -4,15 +4,21 @@ import (
"assignment-1/pkg"
"encoding/json"
"fmt"
"log"
"net/http"
)
func Dhandler(w http.ResponseWriter, r *http.Request) {
var d pkg.Diag
pkg.GetDiag(&d)
var diagnostics pkg.Diag
if err := pkg.GetDiag(&diagnostics); err != nil {
w.WriteHeader(http.StatusBadGateway)
_, _ = fmt.Fprintln(w, "An error occured")
}
w.Header().Set("Content-Type", "application/json")
marsh, _ := json.Marshal(d)
_, _ = fmt.Fprintln(w, string(marsh))
if err := json.NewEncoder(w).Encode(&diagnostics); err != nil {
log.Fatal(err)
}
}
......@@ -5,20 +5,23 @@ import (
"encoding/json"
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
func Shandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
specie, code := pkg.GetSpecies(vars["speciesKey"])
s, _ := json.Marshal(specie)
specie, err := pkg.GetSpecies(vars["speciesKey"])
if code == 200 {
if err == nil {
w.Header().Set("Content-Type", "application/json")
_, _ = fmt.Fprintln(w, string(s))
err = json.NewEncoder(w).Encode(&specie)
if err != nil {
log.Fatal(err)
}
} else {
w.WriteHeader(http.StatusBadGateway)
_, _ = fmt.Fprintln(w, http.StatusBadGateway)
_, _ = fmt.Fprintln(w, "An error occured")
}
}
......
......@@ -5,12 +5,11 @@ import (
"github.com/gorilla/mux"
"log"
"net/http"
"os"
)
func main() {
r := mux.NewRouter()
port := os.Getenv("PORT")
port := "5000"//os.Getenv("PORT")
c := r.PathPrefix("/conservation/v1").Methods("GET").Subrouter()
// two handlerpaths makes sure that the caller does not HAVE to specify limit
......
package pkg
import (
"log"
"net/http"
)
const countryApi = "https://restcountries.eu/rest/v2/alpha/"
const occurrenceApi = "http://api.gbif.org/v1/occurrence/search?"
type Country struct {
Code string `json:"alpha2Code"`
CountryName string `json:"name"`
CountryFlag string `json:"flag"`
Code string `json:"code"`
CountryName string `json:"countryname"`
CountryFlag string `json:"countryflag"`
Species []string `json:"species"`
SpeciesKey []int `json:"speciesKey"`
}
type Response struct {
Results []Results `json:"results"`
type tempCountry struct {
Flag string `json:"flag"`
Name string `json:"name"`
}
type response struct {
Results []results `json:"results"`
}
type Results struct {
type results struct {
Species string `json:"species"`
SpeciesKey int `json:"speciesKey"`
CountryCode string `json:"countryCode"`
}
func GetCountryByCode(code, limit string) (Country, int) {
func GetCountryByCode(code, limit string) (Country, error) {
var country Country
var species Response
var tmpC tempCountry
var species response
urlCountry := countryApi + code
urlSpecies := occurrenceApi + "country=" + code + "&limit=" + limit
// gets country info
resp, err := getBody(urlCountry)
// gets country info to temp struct
err := getBody(urlCountry, &tmpC)
if err != nil {
log.Fatal(err)
return Country{}, err
}
if resp.StatusCode != http.StatusOK {
return Country{}, http.StatusBadGateway
}
Unfold(&country, resp)
// gets species in that country
resp, err = getBody(urlSpecies)
// add tmp info to country struct
country.CountryFlag = tmpC.Flag
country.CountryName = tmpC.Name
country.Code = code // was passed with the func call
// gets species in specified country
err = getBody(urlSpecies, &species)
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
return Country{}, http.StatusBadGateway
return Country{}, err
}
Unfold(&species, resp)
// adds species-keys & specie-names to the country struct, ensuring no dupes
check := make(map[Results]bool)
check := make(map[results]bool)
for i, _ := range species.Results {
// check that species is not already added
if !check[species.Results[i]] {
check[species.Results[i]] = true
country.SpeciesKey = append(country.SpeciesKey, species.Results[i].SpeciesKey)
country.Species = append(country.Species, species.Results[i].Species)
// if any "failed" species exist, exclude them
if species.Results[i].SpeciesKey != 0 {
check[species.Results[i]] = true
country.SpeciesKey = append(country.SpeciesKey, species.Results[i].SpeciesKey)
country.Species = append(country.Species, species.Results[i].Species)
}
}
}
return country, http.StatusOK
return country, nil
}
......
package pkg
import (
"log"
"fmt"
"net/http"
"time"
)
const gbifApi = "http://api.gbif.org/v1/"
const restApi = "https://restcountries.eu/rest/v2"
var startTime time.Time
// starts counting time since app deployment
var startTime time.Time
func init() {
startTime = time.Now()
}
type Diag struct {
Gbif int `json:"gbif"`
Restcountries int `json:"restcountries"`
Version string `json:"version"`
Uptime int `json:"uptime"`
Gbif int `json:"gbif"`
Restcountries int `json:"restcountries"`
Version string `json:"version"`
Uptime int `json:"uptime"`
}
func GetDiag(d* Diag) {
getGbifStatus(d)
getRestStatus(d)
func GetDiag(d* Diag) error {
if err := getGbifStatus(d); err != nil{
return fmt.Errorf("error occured while contacting GBIF API: %s", err)
}
if err := getRestStatus(d); err != nil {
return fmt.Errorf("error occured while contacting Restcountries API: %s", err)
}
getVersion(d)
getUptime(d)
return nil
}
func getGbifStatus(d *Diag) {
func getGbifStatus(d *Diag) error {
resp, err := http.Get(gbifApi)
if err != nil {
log.Fatal(err)
return err
}
d.Gbif = resp.StatusCode
return nil
}
func getRestStatus(d *Diag) {
func getRestStatus(d *Diag) error {
resp, err := http.Get(restApi)
if err != nil {
log.Fatal(err)
return err
}
d.Restcountries = resp.StatusCode
return nil
}
func getVersion(d *Diag) {
......
......@@ -2,49 +2,52 @@ package pkg
import (
"encoding/json"
"log"
"fmt"
"net/http"
)
func Unfold (m Mashup, response *http.Response) {
m.unmarshal(response)
// allowing access to "overloaded" functions
func unfold (m mashup, response *http.Response) error {
return m.unmarshal(response)
}
type Mashup interface {
unmarshal(response *http.Response)
// basically overloading the function
type mashup interface {
unmarshal(response *http.Response) error
}
func (c *Country) unmarshal(resp *http.Response) {
func (c *tempCountry) unmarshal(resp *http.Response) error {
err := json.NewDecoder(resp.Body).Decode(&c)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
return err
}
func (r *Response) unmarshal(resp *http.Response) {
func (r *response) unmarshal(resp *http.Response) error {
err := json.NewDecoder(resp.Body).Decode(&r)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
return err
}
func (s *Specie) unmarshal(resp *http.Response) () {
func (s *Specie) unmarshal(resp *http.Response) error {
err := json.NewDecoder(resp.Body).Decode(&s)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
return err
}
// parses httpresponse as a string used later for parsing
func getBody(url string) (*http.Response, error) {
resp, err:= http.Get(url)
func getBody(url string, m mashup) error {
resp, err := http.Get(url)
if err != nil {
return nil, err
return err
}
return resp, nil
err = unfold(m, resp)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("status not 200 OK, got: %d", resp.StatusCode)
}
return nil
}
\ No newline at end of file
package pkg
import (
"log"
"net/http"
)
const speciesApi = "http://api.gbif.org/v1/species/"
type Specie struct {
......@@ -20,28 +15,21 @@ type Specie struct {
Year string `json:"year"`
}
func GetSpecies(key string) (Specie, int) {
func GetSpecies(key string) (Specie, error) {
var specie Specie
url := speciesApi + key
resp, err := getBody(url)
err := getBody(url, &specie)
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
return Specie{}, http.StatusBadGateway
return Specie{}, err
}
Unfold(&specie, resp)
// supplies the json keys not provided in the first request (year)
url = url + "/name"
resp, err = getBody(url)
err = getBody(url, &specie)
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
return Specie{}, http.StatusBadGateway
return Specie{}, err
}
Unfold(&specie, resp)
return specie, http.StatusOK
return specie, nil
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment