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