29
29
// SetAnnotations adds key/value pairs to annotations in MongoDB.
30
func SetAnnotations(entity GlobalEntity, st *State, annotations map[string]string) (err error) {
30
func (st *State) SetAnnotations(entity GlobalEntity, annotations map[string]string) (err error) {
31
31
defer errors.DeferredAnnotatef(&err, "cannot update annotations on %s", entity.Tag())
32
32
if len(annotations) == 0 {
64
64
return nil, fmt.Errorf("%s no longer exists", entity.Tag())
66
return insertAnnotationsOps(entity, st, toInsert)
66
return insertAnnotationsOps(st, entity, toInsert)
68
return updateAnnotations(entity, st, toUpdate, toRemove), nil
68
return updateAnnotations(st, entity, toUpdate, toRemove), nil
70
70
return st.run(buildTxn)
73
// Annotations returns all the annotations corresponding to an entity.
74
func (st *State) Annotations(entity GlobalEntity) (map[string]string, error) {
75
doc := new(annotatorDoc)
76
annotations, closer := st.getCollection(annotationsC)
78
err := annotations.FindId(entity.globalKey()).One(doc)
79
if err == mgo.ErrNotFound {
80
// Returning an empty map if there are no annotations.
81
return make(map[string]string), nil
84
return nil, errors.Trace(err)
86
return doc.Annotations, nil
89
// Annotation returns the annotation value corresponding to the given key.
90
// If the requested annotation is not found, an empty string is returned.
91
func (st *State) Annotation(entity GlobalEntity, key string) (string, error) {
92
ann, err := st.Annotations(entity)
94
return "", errors.Trace(err)
73
99
// insertAnnotationsOps returns the operations required to insert annotations in MongoDB.
74
func insertAnnotationsOps(entity GlobalEntity, st *State, toInsert map[string]string) ([]txn.Op, error) {
100
func insertAnnotationsOps(st *State, entity GlobalEntity, toInsert map[string]string) ([]txn.Op, error) {
75
101
tag := entity.Tag()
83
109
Annotations: toInsert,
113
switch tag := tag.(type) {
87
114
case names.EnvironTag:
115
env, err := st.GetEnvironment(tag)
117
return nil, errors.Annotatef(err, "inserting annotations")
119
if env.UUID() == env.doc.ServerUUID {
120
// This is a state server environment, and
121
// cannot be removed. Ergo, we can skip the
122
// existence check below.
90
// If the entity is not the environment, add a DocExists check on the
126
// If the entity is not the state server environment, add a DocExists check on the
91
127
// entity document, in order to avoid possible races between entity
92
128
// removal and annotation creation.
93
129
coll, id, err := st.tagToCollectionAndId(tag)
104
140
// updateAnnotations returns the operations required to update or remove annotations in MongoDB.
105
func updateAnnotations(entity GlobalEntity, st *State, toUpdate, toRemove bson.M) []txn.Op {
141
func updateAnnotations(st *State, entity GlobalEntity, toUpdate, toRemove bson.M) []txn.Op {
106
142
return []txn.Op{{
108
144
Id: st.docID(entity.globalKey()),
114
// Annotations returns all the annotations corresponding to an entity.
115
func Annotations(entity GlobalEntity, st *State) (map[string]string, error) {
116
doc := new(annotatorDoc)
117
annotations, closer := st.getCollection(annotationsC)
119
err := annotations.FindId(entity.globalKey()).One(doc)
120
if err == mgo.ErrNotFound {
121
// Returning an empty map if there are no annotations.
122
return make(map[string]string), nil
125
return nil, errors.Trace(err)
127
return doc.Annotations, nil
130
// Annotation returns the annotation value corresponding to the given key.
131
// If the requested annotation is not found, an empty string is returned.
132
func Annotation(entity GlobalEntity, st *State, key string) (string, error) {
133
ann, err := Annotations(entity, st)
135
return "", errors.Trace(err)
140
150
// annotationRemoveOp returns an operation to remove a given annotation
141
151
// document from MongoDB.
142
152
func annotationRemoveOp(st *State, id string) txn.Op {