github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/logfwd/lastsent.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package logfwd 5 6 import ( 7 "io" 8 9 "github.com/juju/errors" 10 "gopkg.in/juju/names.v2" 11 12 "github.com/juju/juju/apiserver/common" 13 "github.com/juju/juju/apiserver/facade" 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/state" 16 ) 17 18 func init() { 19 common.RegisterStandardFacade("LogForwarding", 1, func(st *state.State, _ facade.Resources, auth facade.Authorizer) (*LogForwardingAPI, error) { 20 return NewLogForwardingAPI(&stateAdapter{st}, auth) 21 }) 22 } 23 24 // LastSentTracker exposes the functionality of state.LastSentTracker. 25 type LastSentTracker interface { 26 io.Closer 27 28 // Get retrieves the record ID and timestamp. 29 Get() (recID int64, recTimestamp int64, err error) 30 31 // Set records the record ID and timestamp. 32 Set(recID int64, recTimestamp int64) error 33 } 34 35 // LogForwardingState supports interacting with state for the 36 // LogForwarding facade. 37 type LogForwardingState interface { 38 // NewLastSentTracker creates a new tracker for the given model 39 // and log sink. 40 NewLastSentTracker(tag names.ModelTag, sink string) LastSentTracker 41 } 42 43 // LogForwardingAPI is the concrete implementation of the api end point. 44 type LogForwardingAPI struct { 45 state LogForwardingState 46 } 47 48 // NewLogForwardingAPI creates a new server-side logger API end point. 49 func NewLogForwardingAPI(st LogForwardingState, auth facade.Authorizer) (*LogForwardingAPI, error) { 50 if !auth.AuthMachineAgent() { // the controller's machine agent 51 return nil, common.ErrPerm 52 } 53 api := &LogForwardingAPI{ 54 state: st, 55 } 56 return api, nil 57 } 58 59 // GetLastSent is a bulk call that gets the log forwarding "last sent" 60 // record ID for each requested target. 61 func (api *LogForwardingAPI) GetLastSent(args params.LogForwardingGetLastSentParams) params.LogForwardingGetLastSentResults { 62 results := make([]params.LogForwardingGetLastSentResult, len(args.IDs)) 63 for i, id := range args.IDs { 64 results[i] = api.get(id) 65 } 66 return params.LogForwardingGetLastSentResults{ 67 Results: results, 68 } 69 } 70 71 func (api *LogForwardingAPI) get(id params.LogForwardingID) params.LogForwardingGetLastSentResult { 72 var res params.LogForwardingGetLastSentResult 73 lst, err := api.newLastSentTracker(id) 74 if err != nil { 75 res.Error = common.ServerError(err) 76 return res 77 } 78 defer lst.Close() 79 80 recID, recTimestamp, err := lst.Get() 81 if err != nil { 82 res.Error = common.ServerError(err) 83 if errors.Cause(err) == state.ErrNeverForwarded { 84 res.Error.Code = params.CodeNotFound 85 } 86 return res 87 } 88 res.RecordID = recID 89 res.RecordTimestamp = recTimestamp 90 return res 91 } 92 93 // SetLastSent is a bulk call that sets the log forwarding "last sent" 94 // record ID for each requested target. 95 func (api *LogForwardingAPI) SetLastSent(args params.LogForwardingSetLastSentParams) params.ErrorResults { 96 results := make([]params.ErrorResult, len(args.Params), len(args.Params)) 97 for i, arg := range args.Params { 98 results[i].Error = api.set(arg) 99 } 100 return params.ErrorResults{ 101 Results: results, 102 } 103 } 104 105 func (api *LogForwardingAPI) set(arg params.LogForwardingSetLastSentParam) *params.Error { 106 lst, err := api.newLastSentTracker(arg.LogForwardingID) 107 if err != nil { 108 return common.ServerError(err) 109 } 110 defer lst.Close() 111 112 err = lst.Set(arg.RecordID, arg.RecordTimestamp) 113 return common.ServerError(err) 114 } 115 116 func (api *LogForwardingAPI) newLastSentTracker(id params.LogForwardingID) (LastSentTracker, error) { 117 tag, err := names.ParseModelTag(id.ModelTag) 118 if err != nil { 119 return nil, err 120 } 121 tracker := api.state.NewLastSentTracker(tag, id.Sink) 122 return tracker, nil 123 } 124 125 type stateAdapter struct { 126 *state.State 127 } 128 129 // NewLastSentTracker implements LogForwardingState. 130 func (st stateAdapter) NewLastSentTracker(tag names.ModelTag, sink string) LastSentTracker { 131 return state.NewLastSentLogTracker(st, tag.Id(), sink) 132 }