Skip to content
This repository has been archived by the owner on May 3, 2018. It is now read-only.

Commit

Permalink
Merge pull request #3 from Financial-Times/AddCountIdsReloadEndpoints
Browse files Browse the repository at this point in the history
Added count ids reload endpoints
  • Loading branch information
scott-ace-newton authored Nov 15, 2016
2 parents 8da9b2d + 5cae8dc commit 613341c
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 23 deletions.
39 changes: 39 additions & 0 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/gorilla/mux"
"net/http"
"strconv"
)

type locationsHandler struct {
Expand Down Expand Up @@ -43,6 +44,44 @@ func (h *locationsHandler) getLocations(writer http.ResponseWriter, req *http.Re
writeJSONResponse(obj, found, writer)
}

func (h *locationsHandler) getCount(writer http.ResponseWriter, req *http.Request) {
count := h.service.getLocationCount()
_, err := writer.Write([]byte(strconv.Itoa(count)))
if err != nil {
log.Warnf("Couldn't write count to HTTP response. count=%d %v\n", count, err)
writer.WriteHeader(http.StatusInternalServerError)
}
}

func (h *locationsHandler) getIds(writer http.ResponseWriter, req *http.Request) {
ids := h.service.getLocationIds()
writer.Header().Add("Content-Type", "text/plain")
if len(ids) == 0 {
writer.WriteHeader(http.StatusOK)
return
}
enc := json.NewEncoder(writer)
type locationId struct {
ID string `json:"id"`
}
for _, id := range ids {
rID := locationId{ID: id}
err := enc.Encode(rID)
if err != nil {
log.Warnf("Couldn't encode to HTTP response location with uuid=%s %v\n", id, err)
continue
}
}
}

func (h *locationsHandler) reload(writer http.ResponseWriter, req *http.Request) {
err := h.service.reload()
if err != nil {
log.Warnf("Problem reloading terms from TME: %v", err)
writer.WriteHeader(http.StatusInternalServerError)
}
}

func (h *locationsHandler) getLocationByUUID(writer http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
uuid := vars["uuid"]
Expand Down
26 changes: 26 additions & 0 deletions handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
const testUUID = "bba39990-c78d-3629-ae83-808c333c6dbc"
const getLocationsResponse = `[{"apiUrl":"http://localhost:8080/transformers/locations/bba39990-c78d-3629-ae83-808c333c6dbc"}]`
const getLocationByUUIDResponse = `{"uuid":"bba39990-c78d-3629-ae83-808c333c6dbc","alternativeIdentifiers":{"TME":["MTE3-U3ViamVjdHM="],"uuids":["bba39990-c78d-3629-ae83-808c333c6dbc"]},"prefLabel":"SomeLocation","type":"Location"}`
const getLocationsCountResponse = `1`
const getLocationsIdsResponse = `{"id":"bba39990-c78d-3629-ae83-808c333c6dbc"}`

func TestHandlers(t *testing.T) {
assert := assert.New(t)
Expand All @@ -28,6 +30,8 @@ func TestHandlers(t *testing.T) {
{"Not found - get location by uuid", newRequest("GET", fmt.Sprintf("/transformers/locations/%s", testUUID)), &dummyService{found: false, locations: []location{location{}}}, http.StatusNotFound, "application/json", ""},
{"Success - get locations", newRequest("GET", "/transformers/locations"), &dummyService{found: true, locations: []location{location{UUID: testUUID}}}, http.StatusOK, "application/json", getLocationsResponse},
{"Not found - get locations", newRequest("GET", "/transformers/locations"), &dummyService{found: false, locations: []location{}}, http.StatusNotFound, "application/json", ""},
{"Test Location Count", newRequest("GET", "/transformers/locations/__count"), &dummyService{found: true, locations: []location{location{UUID: testUUID}}}, http.StatusOK, "text/plain", getLocationsCountResponse},
{"Test Location Ids", newRequest("GET", "/transformers/locations/__ids"), &dummyService{found: true, locations: []location{location{UUID: testUUID}}}, http.StatusOK, "text/plain", getLocationsIdsResponse},
}

for _, test := range tests {
Expand All @@ -50,6 +54,9 @@ func router(s locationService) *mux.Router {
m := mux.NewRouter()
h := newLocationsHandler(s)
m.HandleFunc("/transformers/locations", h.getLocations).Methods("GET")
m.HandleFunc("/transformers/locations/__ids", h.getIds).Methods("GET")
m.HandleFunc("/transformers/locations/__count", h.getCount).Methods("GET")
m.HandleFunc("/transformers/locations/__reload", h.reload).Methods("POST")
m.HandleFunc("/transformers/locations/{uuid}", h.getLocationByUUID).Methods("GET")
return m
}
Expand All @@ -74,3 +81,22 @@ func (s *dummyService) getLocationByUUID(uuid string) (location, bool) {
func (s *dummyService) checkConnectivity() error {
return nil
}

func (s *dummyService) getLocationCount() int {
return len(s.locations)
}

func (s *dummyService) getLocationIds() []string {
i := 0
keys := make([]string, len(s.locations))

for _, t := range s.locations {
keys[i] = t.UUID
i++
}
return keys
}

func (s *dummyService) reload() error {
return nil
}
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ func main() {
m.HandleFunc("/__gtg", h.GoodToGo)

m.HandleFunc("/transformers/locations", h.getLocations).Methods("GET")
m.HandleFunc("/transformers/locations/__count", h.getCount).Methods("GET")
m.HandleFunc("/transformers/locations/__ids", h.getIds).Methods("GET")
m.HandleFunc("/transformers/locations/__reload", h.reload).Methods("POST")
m.HandleFunc("/transformers/locations/{uuid}", h.getLocationByUUID).Methods("GET")

http.Handle("/", m)
Expand Down
64 changes: 41 additions & 23 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ type locationService interface {
getLocations() ([]locationLink, bool)
getLocationByUUID(uuid string) (location, bool)
checkConnectivity() error
getLocationCount() int
getLocationIds() []string
reload() error
}

type locationServiceImpl struct {
Expand All @@ -27,35 +30,13 @@ type locationServiceImpl struct {

func newLocationService(repo tmereader.Repository, baseURL string, taxonomyName string, maxTmeRecords int) (locationService, error) {
s := &locationServiceImpl{repository: repo, baseURL: baseURL, taxonomyName: taxonomyName, maxTmeRecords: maxTmeRecords}
err := s.init()
err := s.reload()
if err != nil {
return &locationServiceImpl{}, err
}
return s, nil
}

func (s *locationServiceImpl) init() error {
s.locationsMap = make(map[string]location)
responseCount := 0
log.Printf("Fetching locations from TME\n")
for {
terms, err := s.repository.GetTmeTermsFromIndex(responseCount)
if err != nil {
return err
}

if len(terms) < 1 {
log.Printf("Finished fetching locations from TME\n")
break
}
s.initLocationsMap(terms)
responseCount += s.maxTmeRecords
}
log.Printf("Added %d location links\n", len(s.locationLinks))

return nil
}

func (s *locationServiceImpl) getLocations() ([]locationLink, bool) {
if len(s.locationLinks) > 0 {
return s.locationLinks, true
Expand Down Expand Up @@ -85,3 +66,40 @@ func (s *locationServiceImpl) initLocationsMap(terms []interface{}) {
s.locationLinks = append(s.locationLinks, locationLink{APIURL: s.baseURL + top.UUID})
}
}

func (s *locationServiceImpl) getLocationCount() int {
return len(s.locationLinks)
}

func (s *locationServiceImpl) getLocationIds() []string {
i := 0
keys := make([]string, len(s.locationsMap))

for k := range s.locationsMap {
keys[i] = k
i++
}
return keys
}

func (s *locationServiceImpl) reload() error {
s.locationsMap = make(map[string]location)
responseCount := 0
log.Println("Fetching locations from TME")
for {
terms, err := s.repository.GetTmeTermsFromIndex(responseCount)
if err != nil {
return err
}

if len(terms) < 1 {
log.Println("Finished fetching locations from TME")
break
}
s.initLocationsMap(terms)
responseCount += s.maxTmeRecords
}
log.Printf("Added %d location links\n", len(s.locationLinks))

return nil
}

0 comments on commit 613341c

Please sign in to comment.