github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/state/apiserver/common/unitswatcher.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "launchpad.net/juju-core/state" 8 "launchpad.net/juju-core/state/api/params" 9 "launchpad.net/juju-core/state/watcher" 10 ) 11 12 // UnitsWatcher implements a common WatchUnits method for use by 13 // various facades. 14 type UnitsWatcher struct { 15 st state.EntityFinder 16 resources *Resources 17 getCanWatch GetAuthFunc 18 } 19 20 // NewUnitsWatcher returns a new UnitsWatcher. The GetAuthFunc will be 21 // used on each invocation of WatchUnits to determine current 22 // permissions. 23 func NewUnitsWatcher(st state.EntityFinder, resources *Resources, getCanWatch GetAuthFunc) *UnitsWatcher { 24 return &UnitsWatcher{ 25 st: st, 26 resources: resources, 27 getCanWatch: getCanWatch, 28 } 29 } 30 31 func (u *UnitsWatcher) watchOneEntityUnits(canWatch AuthFunc, tag string) (params.StringsWatchResult, error) { 32 nothing := params.StringsWatchResult{} 33 if !canWatch(tag) { 34 return nothing, ErrPerm 35 } 36 entity0, err := u.st.FindEntity(tag) 37 if err != nil { 38 return nothing, err 39 } 40 entity, ok := entity0.(state.UnitsWatcher) 41 if !ok { 42 return nothing, NotSupportedError(tag, "watching units") 43 } 44 watch := entity.WatchUnits() 45 // Consume the initial event and forward it to the result. 46 if changes, ok := <-watch.Changes(); ok { 47 return params.StringsWatchResult{ 48 StringsWatcherId: u.resources.Register(watch), 49 Changes: changes, 50 }, nil 51 } 52 return nothing, watcher.MustErr(watch) 53 } 54 55 // WatchUnits starts a StringsWatcher to watch all units belonging to 56 // to any entity (machine or service) passed in args. 57 func (u *UnitsWatcher) WatchUnits(args params.Entities) (params.StringsWatchResults, error) { 58 result := params.StringsWatchResults{ 59 Results: make([]params.StringsWatchResult, len(args.Entities)), 60 } 61 if len(args.Entities) == 0 { 62 return result, nil 63 } 64 canWatch, err := u.getCanWatch() 65 if err != nil { 66 return params.StringsWatchResults{}, err 67 } 68 for i, entity := range args.Entities { 69 entityResult, err := u.watchOneEntityUnits(canWatch, entity.Tag) 70 result.Results[i] = entityResult 71 result.Results[i].Error = ServerError(err) 72 } 73 return result, nil 74 }