func fieldmetricsummaryHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { switch r.Method { case "GET": switch r.Header.Get("Accept") { case "application/x-protobuf": if res := weft.CheckQuery(r, []string{}, []string{"typeID"}); !res.Ok { return res } h.Set("Content-Type", "application/x-protobuf") return fieldLatestProto(r, h, b) case "image/svg+xml": if res := weft.CheckQuery(r, []string{"bbox", "typeID", "width"}, []string{}); !res.Ok { return res } h.Set("Content-Type", "image/svg+xml") return fieldLatestSvg(r, h, b) case "application/vnd.geo+json": if res := weft.CheckQuery(r, []string{"typeID"}, []string{}); !res.Ok { return res } h.Set("Content-Type", "application/vnd.geo+json") return fieldLatestGeoJSON(r, h, b) default: if res := weft.CheckQuery(r, []string{"bbox", "typeID", "width"}, []string{}); !res.Ok { return res } h.Set("Content-Type", "image/svg+xml") return fieldLatestSvg(r, h, b) } default: return &weft.MethodNotAllowed } }
func datacompletenessHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { switch r.Method { case "GET": switch r.Header.Get("Accept") { case "image/svg+xml": if res := weft.CheckQuery(r, []string{"siteID", "typeID"}, []string{"plot", "resolution", "yrange"}); !res.Ok { return res } h.Set("Content-Type", "image/svg+xml") return dataCompletenessSvg(r, h, b) default: if res := weft.CheckQuery(r, []string{"siteID", "typeID"}, []string{"plot", "resolution", "yrange"}); !res.Ok { return res } h.Set("Content-Type", "image/svg+xml") return dataCompletenessSvg(r, h, b) } case "PUT": if res := weft.CheckQuery(r, []string{"count", "siteID", "time", "typeID"}, []string{}); !res.Ok { return res } return dataCompletenessPut(r, h, b) case "DELETE": if res := weft.CheckQuery(r, []string{"siteID", "typeID"}, []string{}); !res.Ok { return res } return dataCompletenessDelete(r, h, b) default: return &weft.MethodNotAllowed } }
func tagsHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { switch r.Method { case "GET": switch r.Header.Get("Accept") { case "application/x-protobuf": if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } h.Set("Content-Type", "application/x-protobuf") return tagProto(r, h, b) default: return &weft.NotAcceptable } case "PUT": if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } return tagPut(r, h, b) case "DELETE": if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } return tagDelete(r, h, b) default: return &weft.MethodNotAllowed } }
func fieldmetricthresholdHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { switch r.Method { case "GET": switch r.Header.Get("Accept") { case "application/x-protobuf": if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } h.Set("Content-Type", "application/x-protobuf") return fieldThresholdProto(r, h, b) default: return &weft.NotAcceptable } case "PUT": if res := weft.CheckQuery(r, []string{"deviceID", "lower", "typeID", "upper"}, []string{}); !res.Ok { return res } return fieldThresholdPut(r, h, b) case "DELETE": if res := weft.CheckQuery(r, []string{"deviceID", "typeID"}, []string{}); !res.Ok { return res } return fieldThresholdDelete(r, h, b) default: return &weft.MethodNotAllowed } }
func datacompletenesssummaryHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { switch r.Method { case "GET": switch r.Header.Get("Accept") { case "image/svg+xml": if res := weft.CheckQuery(r, []string{"bbox", "typeID", "width"}, []string{}); !res.Ok { return res } h.Set("Content-Type", "image/svg+xml") return dataCompletenessSummarySvg(r, h, b) case "application/x-protobuf": if res := weft.CheckQuery(r, []string{}, []string{"typeID"}); !res.Ok { return res } h.Set("Content-Type", "application/x-protobuf") return dataCompletenessSummaryProto(r, h, b) default: if res := weft.CheckQuery(r, []string{"bbox", "typeID", "width"}, []string{}); !res.Ok { return res } h.Set("Content-Type", "image/svg+xml") return dataCompletenessSummarySvg(r, h, b) } default: return &weft.MethodNotAllowed } }
func appmetricHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { switch r.Method { case "GET": switch r.Header.Get("Accept") { case "image/svg+xml": if res := weft.CheckQuery(r, []string{"applicationID", "group"}, []string{"resolution", "sourceID", "yrange"}); !res.Ok { return res } h.Set("Content-Type", "image/svg+xml") return appMetricSvg(r, h, b) case "text/csv": if res := weft.CheckQuery(r, []string{"applicationID", "group"}, []string{"endDate", "resolution", "sourceID", "startDate"}); !res.Ok { return res } h.Set("Content-Type", "text/csv") return appMetricCsv(r, h, b) default: if res := weft.CheckQuery(r, []string{"applicationID", "group"}, []string{"resolution", "sourceID", "yrange"}); !res.Ok { return res } h.Set("Content-Type", "image/svg+xml") return appMetricSvg(r, h, b) } default: return &weft.MethodNotAllowed } }
func quakesWWWnz(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } path := r.URL.Path[quakesNZServiceLen:] // ..."3/100.json" tokens := strings.Split(path, "/") if len(tokens) != 2 { return weft.BadRequest("Bad URL path.") } var mmi int var err error var count int if mmi, err = strconv.Atoi(tokens[0]); err != nil { return weft.BadRequest("Bad URL path. Invalid mmi.") } if count, err = strconv.Atoi(tokens[1][:len(tokens[1])-5]); err != nil { // len(".json") return weft.BadRequest("Bad URL path. Invalid count.") } var d string err = db.QueryRow(quakesNZWWWSQL, mmi, count).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", JSON) return &weft.StatusOK }
// handler that serves an html page for detailed metric information func metricDetailHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var ( err error ) if res := weft.CheckQuery(r, []string{"deviceID", "typeID"}, []string{}); !res.Ok { return res } // We create a page struct with variables to substitute into the loaded template q := r.URL.Query() deviceID := q.Get("deviceID") typeID := q.Get("typeID") p := metricDetailPage{MtrApiUrl: mtrApiUrl} p.Border.Title = fmt.Sprintf("Detailed Metric Info for deviceID:%s TypeID:%s", deviceID, typeID) p.MetricDetail.DeviceID = deviceID p.MetricDetail.TypeID = typeID if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } if err = metricDetailTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func home(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } return &weft.NotFound }
func fieldPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } p := mtrUiPage{} p.Path = r.URL.Path p.Border.Title = "GeoNet MTR" p.ActiveTab = "Field" if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } var pa panel if pa, err = getFieldSummary(); err != nil { return weft.InternalServerError(err) } p.Panels = []panel{pa} if err = fieldTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
// Proxies sensor *.geojson from S3 func sensorV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{"type"}, []string{}); !res.Ok { return res } t := r.URL.Query().Get("type") if !sensorGeoJSON[t] { return &weft.NotFound } params := &s3.GetObjectInput{ Key: aws.String("delta/" + t + ".geojson"), Bucket: aws.String("api.geonet.org.nz"), } res, err := s3Client.GetObject(params) if err != nil { return weft.InternalServerError(err) } defer res.Body.Close() _, err = b.ReadFrom(res.Body) if err != nil { return weft.InternalServerError(err) } h.Set("Content-Type", V2GeoJSON) h.Set("Surrogate-Control", maxAge3600) return &weft.StatusOK }
func intensityMeasuredLatestV1(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{"type"}, []string{}); !res.Ok { return res } if r.URL.Query().Get("type") != "measured" { return weft.BadRequest("type must be measured.") } var d string err := db.QueryRow( `SELECT row_to_json(fc) FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features FROM (SELECT 'Feature' as type, ST_AsGeoJSON(s.location)::json as geometry, row_to_json(( select l from ( select mmi ) as l )) as properties from (select location, mmi FROM impact.intensity_measured) as s ) As f ) as fc`).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V1GeoJSON) return &weft.StatusOK }
func volcanoRegionV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } var err error var volcanoId string if volcanoId, err = getVolcanoIDRegion(r); err != nil { return weft.BadRequest(err.Error()) } var d string err = db.QueryRow(`SELECT row_to_json(fc) FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features FROM (SELECT 'Feature' as type, ST_AsGeoJSON(r.region)::json as geometry, row_to_json((SELECT l FROM ( SELECT id, title ) as l )) as properties FROM haz.volcano as r where id = $1) as f ) as fc;`, volcanoId).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V2GeoJSON) return &weft.StatusOK }
func quakeV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } if len(r.URL.Query()) != 0 { return weft.BadRequest("incorrect number of query parameters.") } var publicID string var res *weft.Result if publicID, res = getPublicIDPath(r); !res.Ok { return res } var d string err := db.QueryRow(quakeV2SQL, publicID).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V2GeoJSON) return &weft.StatusOK }
func dataSitesPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error if res := weft.CheckQuery(r, []string{}, []string{"status", "typeID"}); !res.Ok { return res } p := mtrUiPage{} p.Path = r.URL.Path p.Border.Title = "GeoNet MTR - Data Sites" p.ActiveTab = "Data" p.MtrApiUrl = mtrApiUrl.String() if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } p.pageParam(r.URL.Query()) if err = p.getSitesList(); err != nil { return weft.InternalServerError(err) } if err = dataTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func valV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } var d string err := db.QueryRow(`SELECT row_to_json(fc) FROM ( SELECT 'FeatureCollection' as type, array_to_json(array_agg(f)) as features FROM (SELECT 'Feature' as type, ST_AsGeoJSON(v.location)::json as geometry, row_to_json((SELECT l FROM ( SELECT id AS "volcanoID", title AS "volcanoTitle", alert_level as "level", activity, hazards ) as l )) as properties FROM (haz.volcano JOIN haz.volcanic_alert_level using (alert_level)) as v ) As f ) as fc`).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V2GeoJSON) return &weft.StatusOK }
func getQuakesWfs(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { //1. check query parameters if res := weft.CheckQuery(r, requiredParams, optionalParams); !res.Ok { return res } v := r.URL.Query() params, err := getQueryParams(v) if err != nil { return weft.BadRequest(err.Error()) } if params.outputFormat == "JSON" { return getQuakesGeoJson(r, h, b, params) } else if params.outputFormat == "CSV" { return getQuakesCsv(r, h, b, params) } else if params.outputFormat == "GML2" { return getQuakesGml2(r, h, b, params) //text/xml; subtype=gml/3.2 } else if params.outputFormat == "TEXT/XML" && params.subType == "GML/3.2" { return getQuakesGml3(r, h, b, params) } else { return weft.BadRequest("Invalid outputFormat") } return &weft.StatusOK }
func searchPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error var p *searchPage if res := weft.CheckQuery(r, []string{"tagQuery"}, []string{"page"}); !res.Ok { return res } r.ParseForm() tagQuery := r.FormValue("tagQuery") // Javascript should handle empty query value // Non existent value comes from unauthorized submit if tagQuery == "" { return weft.BadRequest("missing required query parameter: tagQuery") } if p, err = newSearchPage(mtrApiUrl); err != nil { return weft.BadRequest("error creating searchPage object") } if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } if err = p.matchingMetrics(tagQuery); err != nil { return weft.InternalServerError(err) } if err := tagSearchTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
// fetches SC3ML and turns it into a protobuf. func quakeTechnicalProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } by, res := getBytes(s3+strings.TrimPrefix(r.URL.Path, "/quake/technical/")+".xml", "") if !res.Ok { return res } q, err := sc3ml.QuakeTechnical(by) if err != nil { return weft.ServiceUnavailableError(err) } m, err := proto.Marshal(&q) if err != nil { return weft.ServiceUnavailableError(err) } b.Write(m) h.Set("Content-Type", protobuf) return &weft.StatusOK }
func quakeProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } var q haz.Quake var res *weft.Result if q.PublicID, res = getPublicIDPath(r); !res.Ok { return res } var t time.Time var mt time.Time var err error if err = db.QueryRow(quakeProtoSQL, q.PublicID).Scan(&t, &mt, &q.Depth, &q.Magnitude, &q.Locality, &q.Mmi, &q.Quality, &q.Longitude, &q.Latitude); err != nil { return weft.ServiceUnavailableError(err) } q.Time = &haz.Timestamp{Sec: t.Unix(), Nsec: int64(t.Nanosecond())} q.ModificationTime = &haz.Timestamp{Sec: mt.Unix(), Nsec: int64(mt.Nanosecond())} var by []byte if by, err = proto.Marshal(&q); err != nil { return weft.ServiceUnavailableError(err) } b.Write(by) h.Set("Content-Type", protobuf) return &weft.StatusOK }
func dataPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } // We create a page struct with variables to substitute into the loaded template p := mtrUiPage{} p.Path = r.URL.Path p.Border.Title = "GeoNet MTR - Data" p.ActiveTab = "Data" if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } var pa panel if pa, err = getDataSummary(); err != nil { return weft.InternalServerError(err) } p.Panels = []panel{pa} if err = dataTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
// Contruct a simple page that has several plots (and time intervals as param) for the specified applicationID param func appPlotPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error if res := weft.CheckQuery(r, []string{"applicationID"}, []string{"resolution", "interactive"}); !res.Ok { return res } p := mtrUiPage{} p.Path = r.URL.Path p.MtrApiUrl = mtrApiUrl.String() p.Border.Title = "GeoNet MTR - application ID" p.ActiveTab = "Apps" // get the applicationID and resolution params from the URL p.pageParam(r.URL.Query()) // Resolution not required if we're in "interactive" mode otherwise default is minute if p.Resolution == "" && !p.Interactive { p.Resolution = "minute" } if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } if err = appPlotTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func fieldPlotPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{"deviceID", "typeID"}, []string{"resolution", "interactive"}); !res.Ok { return res } p := mtrUiPage{} p.Path = r.URL.Path p.MtrApiUrl = mtrApiUrl.String() p.Border.Title = "GeoNet MTR - Field" p.ActiveTab = "Field" p.pageParam(r.URL.Query()) if err := p.getFieldMetricTags(); err != nil { return weft.InternalServerError(err) } // Resolution not required if we're in "interactive" mode otherwise default is minute if p.Resolution == "" && !p.Interactive { p.Resolution = "minute" } if err := p.getFieldHistoryLog(); err != nil { return weft.InternalServerError(err) } if err := p.getFieldYLabel(); err != nil { return weft.InternalServerError(err) } // Set thresholds on plot by drawing a box in dygraph. Protobuf contains all thresholds, so select ours u := *mtrApiUrl u.Path = "/field/metric/threshold" var err error var protoData []byte if protoData, err = getBytes(u.String(), "application/x-protobuf"); err != nil { return weft.InternalServerError(err) } var f mtrpb.FieldMetricThresholdResult if err = proto.Unmarshal(protoData, &f); err != nil { return weft.InternalServerError(err) } if f.Result != nil { for _, row := range f.Result { if row.DeviceID == p.DeviceID && row.TypeID == p.TypeID { p.Plt.Thresholds = []float64{float64(row.Lower) * row.Scale, float64(row.Upper) * row.Scale} } } } if err := fieldTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func mapPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } p := mapPage{} p.MtrApiUrl = mtrApiUrl.String() p.Border.Title = "GeoNet MTR - Map" p.ActiveTab = "Map" if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } if err = p.populateTypes(); err != nil { return weft.InternalServerError(err) } s := strings.TrimPrefix(r.URL.Path, "/map") typeExist := false if ArrayContains(s, []string{"", "/"}) { p.TypeID = "" typeExist = true for _, mapdef := range p.Border.MapList { if len(mapdef.TypeIDs) > 0 { p.TypeID = mapdef.TypeIDs[0] p.MapApiUrl = mapdef.ApiUrl break } } } else { s1 := strings.TrimPrefix(s, "/") for _, mapdef := range p.Border.MapList { if ArrayContains(s1, mapdef.TypeIDs) { p.TypeID = s1 p.MapApiUrl = mapdef.ApiUrl typeExist = true break } } } if !typeExist { return weft.InternalServerError(fmt.Errorf("Unknown map type")) } if err = mapTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func tagPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } p := tagPage{} p.Path = r.URL.Path p.Border.Title = "GeoNet MTR" p.ActiveTab = "Tag" if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } ph := strings.TrimPrefix(p.Path, "/tag") if strings.HasPrefix(ph, "/") { ph = ph[1:] } currTab := -1 // Create grouping tabs p.TagTabs = make([]string, 0) for i, k := range tagGrouper { s := k[:1] + "-" + k[len(k)-1:] p.TagTabs = append(p.TagTabs, s) if ph == s { currTab = i } } if currTab == -1 && ph != "" { return weft.BadRequest("Invalid tag index.") } if ph == "" { currTab = 0 } p.Path = p.TagTabs[currTab] for _, t := range p.Border.TagList { c := t[:1] if strings.Contains(tagGrouper[currTab], c) { p.Tags = append(p.Tags, t) } } if err = tagPageTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
// returns a simple state of health page. If heartbeat times in the // DB are old then it also returns an http status of 500. // Not useful for inclusion in app metrics so weft not used. func sohEsb(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", HtmlContent) if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { w.Header().Set("Surrogate-Control", "max-age=86400") w.WriteHeader(http.StatusBadRequest) return } var b bytes.Buffer b.Write([]byte(head)) b.Write([]byte(`<p>Current time is: ` + time.Now().UTC().String() + `</p>`)) b.Write([]byte(`<h3>Messaging</h3>`)) var bad bool var s string var t time.Time b.Write([]byte(`<table><tr><th>Service</th><th>Time Received</th></tr>`)) rows, err := db.Query("select serverid, timereceived from haz.soh") if err == nil { defer rows.Close() for rows.Next() { err := rows.Scan(&s, &t) if err == nil { if t.Before(time.Now().UTC().Add(old)) { bad = true b.Write([]byte(`<tr class="tr error">`)) } else { b.Write([]byte(`<tr>`)) } b.Write([]byte(`<td>` + s + `</td><td>` + t.String() + `</td></tr>`)) } else { bad = true b.Write([]byte(`<tr class="tr error"><td>DB error</td><td>` + err.Error() + `</td></tr>`)) } } rows.Close() } else { log.Printf("ERROR: %v", err) bad = true b.Write([]byte(`<tr class="tr error"><td>DB error</td><td>` + err.Error() + `</td></tr>`)) } b.Write([]byte(`</table>`)) b.Write([]byte(foot)) if bad { w.WriteHeader(http.StatusServiceUnavailable) } b.WriteTo(w) }
func applicationtimerHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { switch r.Method { case "PUT": if res := weft.CheckQuery(r, []string{"applicationID", "average", "count", "fifty", "instanceID", "ninety", "sourceID", "time"}, []string{}); !res.Ok { return res } return applicationTimerPut(r, h, b) default: return &weft.MethodNotAllowed } }
// up is for testing that the app has started e.g., for with load balancers. // It indicates the app is started. It may still be serving errors. // Not useful for inclusion in app metrics so weft not used. func up(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { w.Header().Set("Surrogate-Control", "max-age=86400") w.WriteHeader(http.StatusBadRequest) return } w.Write([]byte("<html><head></head><body>up</body></html>")) }
func applicationmetricHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { switch r.Method { case "PUT": if res := weft.CheckQuery(r, []string{"applicationID", "instanceID", "time", "typeID", "value"}, []string{}); !res.Ok { return res } return applicationMetricPut(r, h, b) default: return &weft.MethodNotAllowed } }
func newsProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } res, err := client.Get(newsURL) defer res.Body.Close() if err != nil { return weft.ServiceUnavailableError(err) } body, err := ioutil.ReadAll(res.Body) if err != nil { return weft.ServiceUnavailableError(err) } f, err := unmarshalNews(body) if err != nil { return weft.ServiceUnavailableError(err) } var n haz.News for _, v := range f.Entries { s := haz.Story{ Title: v.Title, Link: v.Link.Href, } t, err := time.Parse(time.RFC3339, v.Published) if err != nil { return weft.ServiceUnavailableError(err) } ts := haz.Timestamp{Sec: t.Unix(), Nsec: int64(t.Nanosecond())} s.Published = &ts n.Stories = append(n.Stories, &s) } var by []byte if by, err = proto.Marshal(&n); err != nil { return weft.ServiceUnavailableError(err) } b.Write(by) h.Set("Content-Type", protobuf) h.Set("Surrogate-Control", maxAge300) return &weft.StatusOK }