func (asset *Asset) Create(context *ctp.ApiContext) *ctp.HttpError { asset.BuildLinks(context) if !ctp.CreateResource(context, "assets", asset) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not save asset") } return nil }
func (attribute *Attribute) Create(context *ctp.ApiContext) *ctp.HttpError { attribute.BuildLinks(context) if !ctp.CreateResource(context, "attributes", attribute) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not save object") } return nil }
func (res *TaggedResource) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, context.Params[0], ctp.Base64Id(context.Params[1]), res) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } res.BuildLinks(context) return nil }
func (attribute *Attribute) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "attributes", ctp.Base64Id(context.Params[1]), attribute) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } attribute.BuildLinks(context) return nil }
func (account *Account) Create(context *ctp.ApiContext) *ctp.HttpError { var key [24]byte account.BuildLinks(context) if account.Token == "" { _, err := rand.Read(key[:]) if err != nil { return ctp.NewInternalServerError("Error generating key") } account.Token = base64.StdEncoding.EncodeToString(key[:]) } if len(account.AccountTags.WithPrefix("account:")) == 0 { account.AccountTags.Append(ctp.NewTags("account:" + string(account.Id))) } if len(account.AccountTags.WithPrefix("role:")) == 0 { account.AccountTags.Append(ctp.UserRoleTag) } if !ctp.CreateResource(context, "accounts", account) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not save account") } return nil }
func (serviceview *ServiceView) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "serviceViews", ctp.Base64Id(context.Params[1]), serviceview) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } serviceview.BuildLinks(context) return nil }
func (log *LogEntry) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "logs", ctp.Base64Id(context.Params[1]), log) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } log.BuildLinks(context) return nil }
func (metric *Metric) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "metrics", ctp.Base64Id(context.Params[1]), metric) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } metric.BuildLinks(context) return nil }
func (asset *Asset) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "assets", ctp.Base64Id(context.Params[1]), asset) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } asset.BuildLinks(context) return nil }
func (access *Access) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "access", ctp.Base64Id(context.Params[1]), access) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } access.BuildLinks(context) return nil }
func (trigger *Trigger) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "triggers", ctp.Base64Id(context.Params[1]), trigger) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } trigger.Measurement = ctp.ExpandLink(context.CtpBase, trigger.Measurement) trigger.BuildLinks(context) return nil }
func (log *LogEntry) Create(context *ctp.ApiContext) *ctp.HttpError { log.BuildLinks(context) //log.CreationTime = ctp.Now() if !ctp.CreateResource(context, "logs", log) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not save object") } return nil }
func (serviceview *ServiceView) Create(context *ctp.ApiContext) *ctp.HttpError { serviceview.BuildLinks(context) if !ctp.CreateResource(context, "serviceViews", serviceview) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not save object") } return nil }
func (measurement *Measurement) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "measurements", ctp.Base64Id(context.Params[1]), measurement) { return ctp.NewHttpError(http.StatusNotFound, "Not Found") } measurement.Metric = ctp.ExpandLink(context.CtpBase, measurement.Metric) measurement.BuildLinks(context) return nil }
func (metric *Metric) Create(context *ctp.ApiContext) *ctp.HttpError { metric.BuildLinks(context) if !ctp.CreateResource(context, "metrics", metric) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not save object") } return nil }
func (res *TaggedResource) Update(context *ctp.ApiContext, update ctp.ResourceUpdater) *ctp.HttpError { res.BuildLinks(context) if !ctp.UpdateResourcePart(context, context.Params[0], ctp.Base64Id(context.Params[1]), "accessTags", update.Super().AccessTags) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not update object") } res.AccessTags = update.Super().AccessTags return nil }
func (serviceview *ServiceView) Create(context *ctp.ApiContext) *ctp.HttpError { serviceview.BuildLinks(context) // we don't set serviceview.AccessTags it's the admin's job to do so. if !ctp.CreateResource(context, "serviceViews", serviceview) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not save object") } return nil }
func (mux *CtpApiHandlerMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { context, err := ctp.NewApiContext(r, mux.Configuration) if err != nil { ctp.RenderErrorResponse(w, context, ctp.NewHttpError(500, "Context creation failure")) return } defer context.Close() if handlerfunc, ok := ctpUrlMap[context.Signature]; ok { ctp.Log(context, ctp.INFO, "Serving request '%s' with signature '%s'", r.RequestURI, context.Signature) handlerfunc(w, r, context) } else { ctp.Log(nil, ctp.WARNING, "Not found: %s\n", context.Signature) http.NotFound(w, r) } }
func (metric *Metric) Delete(context *ctp.ApiContext) *ctp.HttpError { metricUrl := ctp.NewLink(context.CtpBase, "@/metrics/$", metric.Id) // just to create a clean URL query := context.Session.DB("ctp").C("measurements").Find(bson.M{"metric": metricUrl}) count, err := query.Count() if err != nil { return ctp.NewInternalServerError(err) } if count > 0 { return ctp.NewHttpError(http.StatusConflict, "Metric cannot be deleted because it is still in use by some measurements.") } if !ctp.DeleteResource(context, "metrics", metric.Id) { return ctp.NewInternalServerError("Metric deletion failed") } return nil }
func (trigger *Trigger) Create(context *ctp.ApiContext) *ctp.HttpError { trigger.BuildLinks(context) trigger.Measurement = ctp.ShortenLink(context.CtpBase, trigger.Measurement) if !ctp.IsShortLink(trigger.Measurement) { return ctp.NewBadRequestError("Invalid measurement URL") } ok, err := triggerCheckCondition(context, trigger, nil) if err != nil { return ctp.NewBadRequestErrorf("%s", err.Error()) } if ok { triggerLogAndNotify(context, trigger, nil) } if !ctp.CreateResource(context, "triggers", trigger) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not save object") } return nil }
func (measurement *Measurement) Update(context *ctp.ApiContext, update ctp.ResourceUpdater) *ctp.HttpError { measurement.BuildLinks(context) up, ok := update.(*Measurement) if !ok { return ctp.NewInternalServerError("Updated object is not a measurement") // should never happen } switch context.QueryParam { case "userActivated": switch up.State { case "activated": if measurement.State == "deactivated" { measurement.State = "pending" // FIXME: add backoffice logic for notification of state change? } case "deactivated": measurement.State = "deactivated" measurement.Result = nil default: return ctp.NewBadRequestError("state can only be 'activated' or 'deactivated'") } case "objective": measurement.Objective = up.Objective if err := measurementObjectiveEvaluate(context, measurement); err != nil { return err } case "result": if measurement.State == "deactivated" { return ctp.NewHttpError(http.StatusConflict, "Measurement is not in activated state.") } if measurement.State == "pending" { measurement.State = "activated" } if up.Result == nil { return ctp.NewBadRequestError("No result provided in request") } measurement.Result = up.Result if measurement.Result.UpdateTime.IsZero() { measurement.Result.UpdateTime = ctp.Now() } if err := measurementCheckMetric(context, measurement); err != nil { return err } if measurement.Objective != nil { if err := measurementObjectiveEvaluate(context, measurement); err != nil { return err } } measurementTriggersEvaluate(context, measurement) default: return ctp.NewBadRequestError("invalid query string") // should never happen, because already filtered in serve.go } if !ctp.UpdateResource(context, "measurements", measurement.Id, measurement) { return ctp.NewInternalServerError("Could not update measurement object") } return nil }
func (attribute *Attribute) Delete(context *ctp.ApiContext) *ctp.HttpError { if !attributeDelete(context, attribute.Id) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not delete attribute") } return nil }
func (serviceview *ServiceView) Delete(context *ctp.ApiContext) *ctp.HttpError { if !serviceViewDelete(context, serviceview.Id) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not delete service-view") } return nil }
func (asset *Asset) Delete(context *ctp.ApiContext) *ctp.HttpError { if !assetDelete(context, asset.Id) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not delete asset") } return nil }
func (measurement *Measurement) Delete(context *ctp.ApiContext) *ctp.HttpError { if !measurementDelete(context, measurement.Id) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not delete measurement") } return nil }
func HandleGETCollection(w http.ResponseWriter, r *http.Request, context *ctp.ApiContext) { var item ctp.NamedResource var parent ctp.Resource var query *mgo.Query var collectionType string var skip, page, items int var err error collection := new(Collection) selector := make(bson.M) if name, ok := r.URL.Query()["name"]; ok { selector["name"] = name[0] } page_query := r.URL.Query().Get("page") items_query := r.URL.Query().Get("items") if page_query != "" || items_query != "" { if page_query == "" || items_query == "" { ctp.RenderErrorResponse(w, context, ctp.NewHttpError(http.StatusBadRequest, "Must specify both 'page' and 'items' in query string.")) return } if page, err = strconv.Atoi(page_query); err != nil || page < 0 { ctp.RenderErrorResponse(w, context, ctp.NewHttpError(http.StatusBadRequest, "page must be a positive number.")) return } if items, err = strconv.Atoi(items_query); err != nil || items <= 0 { ctp.RenderErrorResponse(w, context, ctp.NewHttpError(http.StatusBadRequest, "items must be a non-zero positive number.")) } skip = items * page } if !context.AuthenticateClient(w, r) { return } var mgoCollection *mgo.Collection if len(context.Params) == 1 { collectionType = context.Params[0] mgoCollection = context.Session.DB("ctp").C(collectionType) switch collectionType { case "serviceViews": if !context.VerifyAccessTags(w, ctp.UserRoleTag) { return } if !ctp.MatchTags(context.AccountTags, ctp.AdminRoleTag) { selector["accessTags"] = bson.M{"$in": context.AccountTags.WithPrefix("account:")} } case "metrics": if !context.VerifyAccessTags(w, ctp.UserRoleTag) { return } default: if !context.VerifyAccessTags(w, ctp.AdminRoleTag) { return } } } else { if !context.VerifyAccessTags(w, ctp.UserRoleTag) { return } if !ctp.LoadResource(context, context.Params[0], ctp.Base64Id(context.Params[1]), &parent) { ctp.RenderErrorResponse(w, context, ctp.NewNotFoundErrorf("Not found - /%s/%s does not exist", context.Params[0], context.Params[1])) return } if !context.VerifyAccessTags(w, parent.AccessTags) { return } collection.Scope = ctp.NewLink(context.CtpBase, "/$/$", context.Params[0], context.Params[1]) collectionType = context.Params[2] if context.Params[2] == "indicators" { mgoCollection = context.Session.DB("ctp").C("measurements") } else { mgoCollection = context.Session.DB("ctp").C(collectionType) } selector["parent"] = context.Params[1] } query = mgoCollection.Find(selector) collection_length, err := query.Count() if err != nil { ctp.RenderErrorResponse(w, context, ctp.NewInternalServerError(err)) return } query = query.Sort("$natural").Skip(skip).Limit(items) returned_length, err := query.Count() if err != nil { ctp.RenderErrorResponse(w, context, ctp.NewInternalServerError(err)) return } collection.Self = ctp.Link(r.URL.RequestURI()) collection.CollectionLength = collection_length collection.ReturnedLength = returned_length collection.CollectionType = collectionType collection.Items = make([]CollectionItem, 0, returned_length) iter := query.Iter() for iter.Next(&item) { collection.Items = append(collection.Items, CollectionItem{ Link: ctp.NewLink(context.CtpBase, "@/$/$", collectionType, item.Id), Name: item.Name, }) } if err := iter.Close(); err != nil { ctp.RenderErrorResponse(w, context, ctp.NewInternalServerError(err)) return } ctp.RenderJsonResponse(w, context, 200, collection) }
func (trigger *Trigger) Delete(context *ctp.ApiContext) *ctp.HttpError { if !ctp.DeleteResource(context, "triggers", trigger.Id) { return ctp.NewHttpError(http.StatusInternalServerError, "Could not delete trigger") } return nil }