// LoadResource returns an object from the database that matches the specified // resource type and object identifier. func (rc *ResourceController) LoadResource(resourceType string, id bson.ObjectId) (interface{}, error) { // Determine the collection expected to hold the resource c := rc.Database().C(ptm_models.GetCollectionName(resourceType)) result := ptm_models.NewStructForResourceName(resourceType) err := c.Find(bson.M{"_id": id}).One(result) if err != nil { return nil, err } logger.Log.WithFields(logrus.Fields{"result": result}).Debug("LoadResource") return result, nil }
// CreateResource creates an instance of the resource associated with // the request url, writes the body of the request into the new object, // and then persists the object in the database. A unique identifier is // created and associated with the object. A copy of the object that was // stored in the database is returned in the response. func (rc *ResourceController) CreateResource(ctx *gin.Context) { req := ctx.Request resourceType := getResourceType(req.URL) resource := ptm_models.NewStructForResourceName(resourceType) if err := ctx.Bind(resource); err != nil { ctx.AbortWithError(http.StatusBadRequest, err) return } res, err := ptm_models.PersistResource(rc.Database(), resourceType, resource) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, err) return } id := reflect.ValueOf(res).Elem().FieldByName("ID").String() logger.Log.WithFields( logrus.Fields{"res type": resourceType, "id": id}).Info("CreateResource") ctx.Header("Location", responseURL(req, resourceType, id).String()) ctx.JSON(http.StatusCreated, res) }
func (rc *ResourceController) UpdateResource(ctx *gin.Context) { var id bson.ObjectId // Section 9.6 of RFC 2616 says to return 201 if resource didn't already exist // and 200 or 204, otherwise // http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6 var statusCode int = http.StatusOK req := ctx.Request resourceType := getResourceType(req.URL) // Validate id as a bson Object ID id, err := toBsonObjectID(ctx.Param("id")) if err != nil { ctx.AbortWithError(http.StatusBadRequest, err) return } var createdOn reflect.Value // Determine if the resource already exists existing, err := rc.LoadResource(resourceType, id) if err != nil { if err == mgo.ErrNotFound { statusCode = http.StatusCreated } else { ctx.AbortWithError(http.StatusInternalServerError, err) return } } else { // reflect.ValueOf(&n).Elem().FieldByName("N").Set(reflect.ValueOf(ft)) metaField := reflect.ValueOf(existing).Elem().FieldByName("Meta") createdOn = metaField.Elem().FieldByName("CreatedOn") logger.Log.WithFields( logrus.Fields{"createdOn": createdOn}).Info("UpdateResource") } resource := ptm_models.NewStructForResourceName(resourceType) if err := ctx.Bind(resource); err != nil { ctx.AbortWithError(http.StatusInternalServerError, err) return } c := rc.Database().C(ptm_models.GetCollectionName(resourceType)) // Force the ID provided in the URL to be in the resource object reflect.ValueOf(resource).Elem().FieldByName("ID").Set(reflect.ValueOf(id)) ptm_models.UpdateLastUpdatedDate(resource) // Ensure the creation date does not change` metaField := reflect.ValueOf(resource).Elem().FieldByName("Meta") metaField.Elem().FieldByName("CreatedOn").Set(createdOn) createdOn2 := metaField.Elem().FieldByName("CreatedOn") logger.Log.WithFields( logrus.Fields{"createdOn2": createdOn2}).Info("UpdateResource") err = c.Update(bson.M{"_id": id}, resource) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, err) return } logger.Log.WithFields( logrus.Fields{"collection": ptm_models.GetCollectionName(resourceType), "res type": resourceType, "id": id, "createdOn": createdOn}).Info("UpdateResource") ctx.Header("Location", responseURL(req, resourceType, id.Hex()).String()) ctx.JSON(statusCode, resource) }