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  }