github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/api/uniter/relation.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package uniter 5 6 import ( 7 "fmt" 8 9 "github.com/juju/names" 10 11 "github.com/juju/juju/apiserver/params" 12 ) 13 14 // This module implements a subset of the interface provided by 15 // state.Relation, as needed by the uniter API. 16 17 // Relation represents a relation between one or two service 18 // endpoints. 19 type Relation struct { 20 st *State 21 tag names.RelationTag 22 id int 23 life params.Life 24 } 25 26 // Tag returns the relation tag. 27 func (r *Relation) Tag() names.RelationTag { 28 return r.tag 29 } 30 31 // String returns the relation as a string. 32 func (r *Relation) String() string { 33 return r.tag.Id() 34 } 35 36 // Id returns the integer internal relation key. This is exposed 37 // because the unit agent needs to expose a value derived from this 38 // (as JUJU_RELATION_ID) to allow relation hooks to differentiate 39 // between relations with different services. 40 func (r *Relation) Id() int { 41 return r.id 42 } 43 44 // Life returns the relation's current life state. 45 func (r *Relation) Life() params.Life { 46 return r.life 47 } 48 49 // Refresh refreshes the contents of the relation from the underlying 50 // state. It returns an error that satisfies errors.IsNotFound if the 51 // relation has been removed. 52 func (r *Relation) Refresh() error { 53 result, err := r.st.relation(r.tag, r.st.unitTag) 54 if err != nil { 55 return err 56 } 57 // NOTE: The life cycle information is the only 58 // thing that can change - id, tag and endpoint 59 // information are static. 60 r.life = result.Life 61 62 return nil 63 } 64 65 // Endpoint returns the endpoint of the relation for the service the 66 // uniter's managed unit belongs to. 67 func (r *Relation) Endpoint() (*Endpoint, error) { 68 // NOTE: This differs from state.Relation.Endpoint(), because when 69 // talking to the API, there's already an authenticated entity - the 70 // unit, and we can find out its service name. 71 result, err := r.st.relation(r.tag, r.st.unitTag) 72 if err != nil { 73 return nil, err 74 } 75 return &Endpoint{result.Endpoint.Relation}, nil 76 } 77 78 // Unit returns a RelationUnit for the supplied unit. 79 func (r *Relation) Unit(u *Unit) (*RelationUnit, error) { 80 if u == nil { 81 return nil, fmt.Errorf("unit is nil") 82 } 83 result, err := r.st.relation(r.tag, u.tag) 84 if err != nil { 85 return nil, err 86 } 87 return &RelationUnit{ 88 relation: r, 89 unit: u, 90 endpoint: Endpoint{result.Endpoint.Relation}, 91 st: r.st, 92 }, nil 93 }