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 (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 (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 (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 (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 (account *Account) Load(context *ctp.ApiContext) *ctp.HttpError { if !ctp.LoadResource(context, "accounts", ctp.Base64Id(context.Params[1]), account) { return ctp.NewHttpErrorf(http.StatusNotFound, "Account %s not found", context.Params[1]) } account.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 (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 measurementCheckResult(context *ctp.ApiContext, item *Measurement) *ctp.HttpError { var metric Metric if item.Metric == "" { return ctp.NewBadRequestError("Missing metric attribute in measurement.") } if item.Result == nil { return ctp.NewBadRequestError("Missing result attribute in measurement.") } metricParams, ok := ctp.ParseLink(context.CtpBase, "@/metrics/$", item.Metric) if !ok { return ctp.NewBadRequestError("Metric URL is incorrect in measurement") } if !ctp.LoadResource(context, "metrics", ctp.Base64Id(metricParams[0]), &metric) { return ctp.NewBadRequestErrorf("Metric %s does not exist", ctp.ExpandLink(context.CtpBase, item.Metric)) } for _, row := range item.Result.Value { if len(row) != len(metric.ResultFormat) { return ctp.NewBadRequestErrorf("Metric expects %d columns, but result value provides %d", len(metric.ResultFormat), len(row)) } for name, cell := range row { metricDetailFound := false for _, metricDetail := range metric.ResultFormat { if metricDetail.Name == name { metricDetailFound = true kind := reflect.ValueOf(cell).Kind() switch metricDetail.Type { case "number": if kind != reflect.Float64 { return ctp.NewBadRequestError("Metric expects a number, but result is of different type") } case "boolean": if kind != reflect.Bool { return ctp.NewBadRequestError("Metric expects a boolean, but result is of different type") } case "string": if kind != reflect.String { return ctp.NewBadRequestError("Metric expects a string, but result is of different type") } default: return ctp.NewBadRequestError("Metric type information is incorrect") } break // from for } } if !metricDetailFound { return ctp.NewBadRequestErrorf("Metric does not describe '%s', which appears in result", name) } } } return nil }
func measurementCheckMetric(context *ctp.ApiContext, item *Measurement) *ctp.HttpError { var metric Metric if item.Metric == "" { return ctp.NewBadRequestError("Missing metric attribute in measurement.") } metricParams, ok := ctp.ParseLink(context.CtpBase, "@/metrics/$", item.Metric) if !ok { return ctp.NewBadRequestError("Metric URL is incorrect in measurement") } if !ctp.LoadResource(context, "metrics", ctp.Base64Id(metricParams[0]), &metric) { return ctp.NewBadRequestErrorf("Metric %s does not exist", ctp.ExpandLink(context.CtpBase, item.Metric)) } return nil }
func triggerCheckCondition(context *ctp.ApiContext, trigger *Trigger, measurement *Measurement) (bool, error) { if measurement == nil { measurementParams, ok := ctp.ParseLink(context.CtpBase, "@/measurements/$", trigger.Measurement) if !ok { return false, fmt.Errorf("Measurement URL is incorrect") } measurement = new(Measurement) if !ctp.LoadResource(context, "measurements", ctp.Base64Id(measurementParams[0]), measurement) { return false, fmt.Errorf("Measurement %s does not exist", ctp.ExpandLink(context.CtpBase, trigger.Measurement)) } } machine, err := jsmm.Compile(trigger.Condition) if err != nil { return false, ctp.NewBadRequestErrorf("Error in condition specification - %s", err.Error()) } if context.DebugVM { machine.DebugMode(true) } if measurement.State != "activated" { return false, nil } if measurement.Result == nil { ctp.Log(context, ctp.ERROR, "In /measurements/%s, the state is activated but the value is null.", measurement.Id) return false, nil } if err := importMeasurementResultInJSMM(machine, measurement.Result); err != nil { return false, err } v, exception := machine.Execute() if exception != nil { return false, fmt.Errorf("Failed to evaluate condition: %s", exception.Error()) } return v.ToBoolean(), nil }
// HandleGETBaseURI handles a request to the baseURI. // It proceeds differently from other resources, which user the 'handler' paradigm. func HandleGETBaseURI(w http.ResponseWriter, r *http.Request, context *ctp.ApiContext) { if !context.AuthenticateClient(w, r) { ctp.Log(context, ctp.WARNING, "Missing access tags") return } if !context.VerifyAccessTags(w, ctp.UserRoleTag) { ctp.Log(context, ctp.WARNING, "Mismatched access tags for API signature") return } base := new(BaseURI) if !ctp.LoadResource(context, "baseuri", ctp.Base64Id("0"), base) { base.Version = "0" base.Annotation = "Unconfigured ctpd prototype server" } base.BuildLinks(context) ctp.RenderJsonResponse(w, context, 200, base) }
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) }